Actual source code: matrix.c
petsc-3.6.4 2016-04-12
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>
8: #include <petsc/private/isimpl.h>
10: /* Logging support */
11: PetscClassId MAT_CLASSID;
12: PetscClassId MAT_COLORING_CLASSID;
13: PetscClassId MAT_FDCOLORING_CLASSID;
14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_GetSubMatrix;
24: PetscLogEvent MAT_TransposeColoringCreate;
25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34: PetscLogEvent MAT_GetMultiProcBlock;
35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36: PetscLogEvent MAT_ViennaCLCopyToGPU;
37: PetscLogEvent MAT_Merge,MAT_Residual;
38: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
40: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
44: /*@
45: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
47: Logically Collective on Vec
49: Input Parameters:
50: + x - the vector
51: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52: it will create one internally.
54: Output Parameter:
55: . x - the vector
57: Example of Usage:
58: .vb
59: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60: VecSetRandom(x,rctx);
61: PetscRandomDestroy(rctx);
62: .ve
64: Level: intermediate
66: Concepts: vector^setting to random
67: Concepts: random^vector
69: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
70: @*/
71: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
72: {
74: PetscRandom randObj = NULL;
81: if (!rctx) {
82: MPI_Comm comm;
83: PetscObjectGetComm((PetscObject)x,&comm);
84: PetscRandomCreate(comm,&randObj);
85: PetscRandomSetFromOptions(randObj);
86: rctx = randObj;
87: }
89: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
90: (*x->ops->setrandom)(x,rctx);
91: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
93: x->assembled = PETSC_TRUE;
94: PetscRandomDestroy(&randObj);
95: return(0);
96: }
101: /*@
102: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
104: Input Parameter:
105: . A - the matrix
107: Output Parameter:
108: . keptrows - the rows that are not completely zero
110: Level: intermediate
112: @*/
113: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
114: {
119: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
120: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
121: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
122: (*mat->ops->findnonzerorows)(mat,keptrows);
123: return(0);
124: }
128: /*@
129: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
131: Not Collective
133: Input Parameters:
134: . A - the matrix
136: Output Parameters:
137: . a - the diagonal part (which is a SEQUENTIAL matrix)
139: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140: Use caution, as the reference count on the returned matrix is not incremented and it is used as
141: part of the containing MPI Mat's normal operation.
143: Level: advanced
145: @*/
146: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
147: {
148: PetscErrorCode ierr,(*f)(Mat,Mat*);
149: PetscMPIInt size;
155: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
156: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
157: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
158: if (f) {
159: (*f)(A,a);
160: return(0);
161: } else if (size == 1) {
162: *a = A;
163: } else {
164: MatType mattype;
165: MatGetType(A,&mattype);
166: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
167: }
168: return(0);
169: }
173: /*@
174: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
176: Collective on Mat
178: Input Parameters:
179: . mat - the matrix
181: Output Parameter:
182: . trace - the sum of the diagonal entries
184: Level: advanced
186: @*/
187: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
188: {
190: Vec diag;
193: MatCreateVecs(mat,&diag,NULL);
194: MatGetDiagonal(mat,diag);
195: VecSum(diag,trace);
196: VecDestroy(&diag);
197: return(0);
198: }
202: /*@
203: MatRealPart - Zeros out the imaginary part of the matrix
205: Logically Collective on Mat
207: Input Parameters:
208: . mat - the matrix
210: Level: advanced
213: .seealso: MatImaginaryPart()
214: @*/
215: PetscErrorCode MatRealPart(Mat mat)
216: {
222: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
223: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
224: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
225: MatCheckPreallocated(mat,1);
226: (*mat->ops->realpart)(mat);
227: #if defined(PETSC_HAVE_CUSP)
228: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
229: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
230: }
231: #endif
232: #if defined(PETSC_HAVE_VIENNACL)
233: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
234: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
235: }
236: #endif
237: return(0);
238: }
242: /*@C
243: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
245: Collective on Mat
247: Input Parameter:
248: . mat - the matrix
250: Output Parameters:
251: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
252: - ghosts - the global indices of the ghost points
254: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
256: Level: advanced
258: @*/
259: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
260: {
266: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
267: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
268: if (!mat->ops->getghosts) {
269: if (nghosts) *nghosts = 0;
270: if (ghosts) *ghosts = 0;
271: } else {
272: (*mat->ops->getghosts)(mat,nghosts,ghosts);
273: }
274: return(0);
275: }
280: /*@
281: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
283: Logically Collective on Mat
285: Input Parameters:
286: . mat - the matrix
288: Level: advanced
291: .seealso: MatRealPart()
292: @*/
293: PetscErrorCode MatImaginaryPart(Mat mat)
294: {
300: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
301: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
302: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
303: MatCheckPreallocated(mat,1);
304: (*mat->ops->imaginarypart)(mat);
305: #if defined(PETSC_HAVE_CUSP)
306: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
307: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
308: }
309: #endif
310: #if defined(PETSC_HAVE_VIENNACL)
311: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
312: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
313: }
314: #endif
315: return(0);
316: }
320: /*@
321: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
323: Collective on Mat
325: Input Parameter:
326: . mat - the matrix
328: Output Parameters:
329: + missing - is any diagonal missing
330: - dd - first diagonal entry that is missing (optional)
332: Level: advanced
335: .seealso: MatRealPart()
336: @*/
337: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
338: {
344: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
345: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
346: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
347: (*mat->ops->missingdiagonal)(mat,missing,dd);
348: return(0);
349: }
353: /*@C
354: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
355: for each row that you get to ensure that your application does
356: not bleed memory.
358: Not Collective
360: Input Parameters:
361: + mat - the matrix
362: - row - the row to get
364: Output Parameters:
365: + ncols - if not NULL, the number of nonzeros in the row
366: . cols - if not NULL, the column numbers
367: - vals - if not NULL, the values
369: Notes:
370: This routine is provided for people who need to have direct access
371: to the structure of a matrix. We hope that we provide enough
372: high-level matrix routines that few users will need it.
374: MatGetRow() always returns 0-based column indices, regardless of
375: whether the internal representation is 0-based (default) or 1-based.
377: For better efficiency, set cols and/or vals to NULL if you do
378: not wish to extract these quantities.
380: The user can only examine the values extracted with MatGetRow();
381: the values cannot be altered. To change the matrix entries, one
382: must use MatSetValues().
384: You can only have one call to MatGetRow() outstanding for a particular
385: matrix at a time, per processor. MatGetRow() can only obtain rows
386: associated with the given processor, it cannot get rows from the
387: other processors; for that we suggest using MatGetSubMatrices(), then
388: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
389: is in the global number of rows.
391: Fortran Notes:
392: The calling sequence from Fortran is
393: .vb
394: MatGetRow(matrix,row,ncols,cols,values,ierr)
395: Mat matrix (input)
396: integer row (input)
397: integer ncols (output)
398: integer cols(maxcols) (output)
399: double precision (or double complex) values(maxcols) output
400: .ve
401: where maxcols >= maximum nonzeros in any row of the matrix.
404: Caution:
405: Do not try to change the contents of the output arrays (cols and vals).
406: In some cases, this may corrupt the matrix.
408: Level: advanced
410: Concepts: matrices^row access
412: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
413: @*/
414: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
415: {
417: PetscInt incols;
422: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
423: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
424: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
425: MatCheckPreallocated(mat,1);
426: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
427: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
428: if (ncols) *ncols = incols;
429: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
430: return(0);
431: }
435: /*@
436: MatConjugate - replaces the matrix values with their complex conjugates
438: Logically Collective on Mat
440: Input Parameters:
441: . mat - the matrix
443: Level: advanced
445: .seealso: VecConjugate()
446: @*/
447: PetscErrorCode MatConjugate(Mat mat)
448: {
449: #if defined(PETSC_USE_COMPLEX)
454: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
455: 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");
456: (*mat->ops->conjugate)(mat);
457: #if defined(PETSC_HAVE_CUSP)
458: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
459: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
460: }
461: #endif
462: #if defined(PETSC_HAVE_VIENNACL)
463: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
464: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
465: }
466: #endif
467: return(0);
468: #else
469: return 0;
470: #endif
471: }
475: /*@C
476: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
478: Not Collective
480: Input Parameters:
481: + mat - the matrix
482: . row - the row to get
483: . ncols, cols - the number of nonzeros and their columns
484: - vals - if nonzero the column values
486: Notes:
487: This routine should be called after you have finished examining the entries.
489: This routine zeros out ncols, cols, and vals. This is to prevent accidental
490: us of the array after it has been restored. If you pass NULL, it will
491: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
493: Fortran Notes:
494: The calling sequence from Fortran is
495: .vb
496: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
497: Mat matrix (input)
498: integer row (input)
499: integer ncols (output)
500: integer cols(maxcols) (output)
501: double precision (or double complex) values(maxcols) output
502: .ve
503: Where maxcols >= maximum nonzeros in any row of the matrix.
505: In Fortran MatRestoreRow() MUST be called after MatGetRow()
506: before another call to MatGetRow() can be made.
508: Level: advanced
510: .seealso: MatGetRow()
511: @*/
512: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
513: {
519: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
520: if (!mat->ops->restorerow) return(0);
521: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
522: if (ncols) *ncols = 0;
523: if (cols) *cols = NULL;
524: if (vals) *vals = NULL;
525: return(0);
526: }
530: /*@
531: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
532: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
534: Not Collective
536: Input Parameters:
537: + mat - the matrix
539: Notes:
540: 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.
542: Level: advanced
544: Concepts: matrices^row access
546: .seealso: MatRestoreRowRowUpperTriangular()
547: @*/
548: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
549: {
555: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
556: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
557: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
558: MatCheckPreallocated(mat,1);
559: (*mat->ops->getrowuppertriangular)(mat);
560: return(0);
561: }
565: /*@
566: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
568: Not Collective
570: Input Parameters:
571: + mat - the matrix
573: Notes:
574: This routine should be called after you have finished MatGetRow/MatRestoreRow().
577: Level: advanced
579: .seealso: MatGetRowUpperTriangular()
580: @*/
581: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
582: {
587: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
588: if (!mat->ops->restorerowuppertriangular) return(0);
589: (*mat->ops->restorerowuppertriangular)(mat);
590: return(0);
591: }
595: /*@C
596: MatSetOptionsPrefix - Sets the prefix used for searching for all
597: Mat options in the database.
599: Logically Collective on Mat
601: Input Parameter:
602: + A - the Mat context
603: - prefix - the prefix to prepend to all option names
605: Notes:
606: A hyphen (-) must NOT be given at the beginning of the prefix name.
607: The first character of all runtime options is AUTOMATICALLY the hyphen.
609: Level: advanced
611: .keywords: Mat, set, options, prefix, database
613: .seealso: MatSetFromOptions()
614: @*/
615: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
616: {
621: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
622: return(0);
623: }
627: /*@C
628: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
629: Mat options in the database.
631: Logically Collective on Mat
633: Input Parameters:
634: + A - the Mat context
635: - prefix - the prefix to prepend to all option names
637: Notes:
638: A hyphen (-) must NOT be given at the beginning of the prefix name.
639: The first character of all runtime options is AUTOMATICALLY the hyphen.
641: Level: advanced
643: .keywords: Mat, append, options, prefix, database
645: .seealso: MatGetOptionsPrefix()
646: @*/
647: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
648: {
653: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
654: return(0);
655: }
659: /*@C
660: MatGetOptionsPrefix - Sets the prefix used for searching for all
661: Mat options in the database.
663: Not Collective
665: Input Parameter:
666: . A - the Mat context
668: Output Parameter:
669: . prefix - pointer to the prefix string used
671: Notes: On the fortran side, the user should pass in a string 'prefix' of
672: sufficient length to hold the prefix.
674: Level: advanced
676: .keywords: Mat, get, options, prefix, database
678: .seealso: MatAppendOptionsPrefix()
679: @*/
680: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
681: {
686: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
687: return(0);
688: }
692: /*@
693: MatSetUp - Sets up the internal matrix data structures for the later use.
695: Collective on Mat
697: Input Parameters:
698: . A - the Mat context
700: Notes:
701: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
703: If a suitable preallocation routine is used, this function does not need to be called.
705: See the Performance chapter of the PETSc users manual for how to preallocate matrices
707: Level: beginner
709: .keywords: Mat, setup
711: .seealso: MatCreate(), MatDestroy()
712: @*/
713: PetscErrorCode MatSetUp(Mat A)
714: {
715: PetscMPIInt size;
720: if (!((PetscObject)A)->type_name) {
721: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
722: if (size == 1) {
723: MatSetType(A, MATSEQAIJ);
724: } else {
725: MatSetType(A, MATMPIAIJ);
726: }
727: }
728: if (!A->preallocated && A->ops->setup) {
729: PetscInfo(A,"Warning not preallocating matrix storage\n");
730: (*A->ops->setup)(A);
731: }
732: A->preallocated = PETSC_TRUE;
733: return(0);
734: }
736: #if defined(PETSC_HAVE_SAWS)
737: #include <petscviewersaws.h>
738: #endif
741: /*@C
742: MatView - Visualizes a matrix object.
744: Collective on Mat
746: Input Parameters:
747: + mat - the matrix
748: - viewer - visualization context
750: Notes:
751: The available visualization contexts include
752: + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
753: . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
754: . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
755: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
757: The user can open alternative visualization contexts with
758: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
759: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
760: specified file; corresponding input uses MatLoad()
761: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
762: an X window display
763: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
764: Currently only the sequential dense and AIJ
765: matrix types support the Socket viewer.
767: The user can call PetscViewerSetFormat() to specify the output
768: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
769: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
770: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
771: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
772: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
773: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
774: format common among all matrix types
775: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
776: format (which is in many cases the same as the default)
777: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
778: size and structure (not the matrix entries)
779: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
780: the matrix structure
782: Options Database Keys:
783: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
784: . -mat_view ::ascii_info_detail - Prints more detailed info
785: . -mat_view - Prints matrix in ASCII format
786: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
787: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
788: . -display <name> - Sets display name (default is host)
789: . -draw_pause <sec> - Sets number of seconds to pause after display
790: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
791: . -viewer_socket_machine <machine> -
792: . -viewer_socket_port <port> -
793: . -mat_view binary - save matrix to file in binary format
794: - -viewer_binary_filename <name> -
795: Level: beginner
797: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
798: viewer is used.
800: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
801: viewer is used.
803: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
804: And then use the following mouse functions:
805: left mouse: zoom in
806: middle mouse: zoom out
807: right mouse: continue with the simulation
809: Concepts: matrices^viewing
810: Concepts: matrices^plotting
811: Concepts: matrices^printing
813: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
814: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
815: @*/
816: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
817: {
818: PetscErrorCode ierr;
819: PetscInt rows,cols,rbs,cbs;
820: PetscBool iascii;
821: PetscViewerFormat format;
822: #if defined(PETSC_HAVE_SAWS)
823: PetscBool issaws;
824: #endif
829: if (!viewer) {
830: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
831: }
834: MatCheckPreallocated(mat,1);
836: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
837: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
838: PetscViewerGetFormat(viewer,&format);
839: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
840: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
841: }
843: #if defined(PETSC_HAVE_SAWS)
844: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
845: #endif
846: if (iascii) {
847: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
848: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
849: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
850: PetscViewerASCIIPushTab(viewer);
851: MatGetSize(mat,&rows,&cols);
852: MatGetBlockSizes(mat,&rbs,&cbs);
853: if (rbs != 1 || cbs != 1) {
854: if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
855: else {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
856: } else {
857: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
858: }
859: if (mat->factortype) {
860: const MatSolverPackage solver;
861: MatFactorGetSolverPackage(mat,&solver);
862: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
863: }
864: if (mat->ops->getinfo) {
865: MatInfo info;
866: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
867: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%g, allocated nonzeros=%g\n",info.nz_used,info.nz_allocated);
868: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
869: }
870: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
871: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
872: }
873: #if defined(PETSC_HAVE_SAWS)
874: } else if (issaws) {
875: PetscMPIInt rank;
877: PetscObjectName((PetscObject)mat);
878: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
879: if (!((PetscObject)mat)->amsmem && !rank) {
880: PetscObjectViewSAWs((PetscObject)mat,viewer);
881: }
882: #endif
883: }
884: if (mat->ops->view) {
885: PetscViewerASCIIPushTab(viewer);
886: (*mat->ops->view)(mat,viewer);
887: PetscViewerASCIIPopTab(viewer);
888: }
889: if (iascii) {
890: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
891: PetscViewerGetFormat(viewer,&format);
892: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
893: PetscViewerASCIIPopTab(viewer);
894: }
895: }
896: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
897: return(0);
898: }
900: #if defined(PETSC_USE_DEBUG)
901: #include <../src/sys/totalview/tv_data_display.h>
902: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
903: {
904: TV_add_row("Local rows", "int", &mat->rmap->n);
905: TV_add_row("Local columns", "int", &mat->cmap->n);
906: TV_add_row("Global rows", "int", &mat->rmap->N);
907: TV_add_row("Global columns", "int", &mat->cmap->N);
908: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
909: return TV_format_OK;
910: }
911: #endif
915: /*@C
916: MatLoad - Loads a matrix that has been stored in binary format
917: with MatView(). The matrix format is determined from the options database.
918: Generates a parallel MPI matrix if the communicator has more than one
919: processor. The default matrix type is AIJ.
921: Collective on PetscViewer
923: Input Parameters:
924: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
925: or some related function before a call to MatLoad()
926: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
928: Options Database Keys:
929: Used with block matrix formats (MATSEQBAIJ, ...) to specify
930: block size
931: . -matload_block_size <bs>
933: Level: beginner
935: Notes:
936: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
937: Mat before calling this routine if you wish to set it from the options database.
939: MatLoad() automatically loads into the options database any options
940: given in the file filename.info where filename is the name of the file
941: that was passed to the PetscViewerBinaryOpen(). The options in the info
942: file will be ignored if you use the -viewer_binary_skip_info option.
944: If the type or size of newmat is not set before a call to MatLoad, PETSc
945: sets the default matrix type AIJ and sets the local and global sizes.
946: If type and/or size is already set, then the same are used.
948: In parallel, each processor can load a subset of rows (or the
949: entire matrix). This routine is especially useful when a large
950: matrix is stored on disk and only part of it is desired on each
951: processor. For example, a parallel solver may access only some of
952: the rows from each processor. The algorithm used here reads
953: relatively small blocks of data rather than reading the entire
954: matrix and then subsetting it.
956: Notes for advanced users:
957: Most users should not need to know the details of the binary storage
958: format, since MatLoad() and MatView() completely hide these details.
959: But for anyone who's interested, the standard binary matrix storage
960: format is
962: $ int MAT_FILE_CLASSID
963: $ int number of rows
964: $ int number of columns
965: $ int total number of nonzeros
966: $ int *number nonzeros in each row
967: $ int *column indices of all nonzeros (starting index is zero)
968: $ PetscScalar *values of all nonzeros
970: PETSc automatically does the byte swapping for
971: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
972: linux, Windows and the paragon; thus if you write your own binary
973: read/write routines you have to swap the bytes; see PetscBinaryRead()
974: and PetscBinaryWrite() to see how this may be done.
976: .keywords: matrix, load, binary, input
978: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
980: @*/
981: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
982: {
984: PetscBool isbinary,flg;
989: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
990: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
992: if (!((PetscObject)newmat)->type_name) {
993: MatSetType(newmat,MATAIJ);
994: }
996: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
997: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
998: (*newmat->ops->load)(newmat,viewer);
999: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1001: flg = PETSC_FALSE;
1002: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1003: if (flg) {
1004: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1005: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1006: }
1007: flg = PETSC_FALSE;
1008: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1009: if (flg) {
1010: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1011: }
1012: return(0);
1013: }
1017: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1018: {
1020: Mat_Redundant *redund = *redundant;
1021: PetscInt i;
1024: if (redund){
1025: if (redund->matseq) { /* via MatGetSubMatrices() */
1026: ISDestroy(&redund->isrow);
1027: ISDestroy(&redund->iscol);
1028: MatDestroy(&redund->matseq[0]);
1029: PetscFree(redund->matseq);
1030: } else {
1031: PetscFree2(redund->send_rank,redund->recv_rank);
1032: PetscFree(redund->sbuf_j);
1033: PetscFree(redund->sbuf_a);
1034: for (i=0; i<redund->nrecvs; i++) {
1035: PetscFree(redund->rbuf_j[i]);
1036: PetscFree(redund->rbuf_a[i]);
1037: }
1038: PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1039: }
1041: if (redund->subcomm) {
1042: PetscCommDestroy(&redund->subcomm);
1043: }
1044: PetscFree(redund);
1045: }
1046: return(0);
1047: }
1051: /*@
1052: MatDestroy - Frees space taken by a matrix.
1054: Collective on Mat
1056: Input Parameter:
1057: . A - the matrix
1059: Level: beginner
1061: @*/
1062: PetscErrorCode MatDestroy(Mat *A)
1063: {
1067: if (!*A) return(0);
1069: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1071: /* if memory was published with SAWs then destroy it */
1072: PetscObjectSAWsViewOff((PetscObject)*A);
1073: if ((*A)->ops->destroy) {
1074: (*(*A)->ops->destroy)(*A);
1075: }
1076: MatDestroy_Redundant(&(*A)->redundant);
1077: MatNullSpaceDestroy(&(*A)->nullsp);
1078: MatNullSpaceDestroy(&(*A)->transnullsp);
1079: MatNullSpaceDestroy(&(*A)->nearnullsp);
1080: PetscLayoutDestroy(&(*A)->rmap);
1081: PetscLayoutDestroy(&(*A)->cmap);
1082: PetscHeaderDestroy(A);
1083: return(0);
1084: }
1088: /*@
1089: MatSetValues - Inserts or adds a block of values into a matrix.
1090: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1091: MUST be called after all calls to MatSetValues() have been completed.
1093: Not Collective
1095: Input Parameters:
1096: + mat - the matrix
1097: . v - a logically two-dimensional array of values
1098: . m, idxm - the number of rows and their global indices
1099: . n, idxn - the number of columns and their global indices
1100: - addv - either ADD_VALUES or INSERT_VALUES, where
1101: ADD_VALUES adds values to any existing entries, and
1102: INSERT_VALUES replaces existing entries with new values
1104: Notes:
1105: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1106: MatSetUp() before using this routine
1108: By default the values, v, are row-oriented. See MatSetOption() for other options.
1110: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1111: options cannot be mixed without intervening calls to the assembly
1112: routines.
1114: MatSetValues() uses 0-based row and column numbers in Fortran
1115: as well as in C.
1117: Negative indices may be passed in idxm and idxn, these rows and columns are
1118: simply ignored. This allows easily inserting element stiffness matrices
1119: with homogeneous Dirchlet boundary conditions that you don't want represented
1120: in the matrix.
1122: Efficiency Alert:
1123: The routine MatSetValuesBlocked() may offer much better efficiency
1124: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1126: Level: beginner
1128: Concepts: matrices^putting entries in
1130: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1131: InsertMode, INSERT_VALUES, ADD_VALUES
1132: @*/
1133: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1134: {
1136: #if defined(PETSC_USE_DEBUG)
1137: PetscInt i,j;
1138: #endif
1143: if (!m || !n) return(0); /* no values to insert */
1147: MatCheckPreallocated(mat,1);
1148: if (mat->insertmode == NOT_SET_VALUES) {
1149: mat->insertmode = addv;
1150: }
1151: #if defined(PETSC_USE_DEBUG)
1152: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1153: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1154: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1156: for (i=0; i<m; i++) {
1157: for (j=0; j<n; j++) {
1158: if (mat->erroriffpe && PetscIsInfOrNanScalar(v[i*n+j]))
1159: #if defined(PETSC_USE_COMPLEX)
1160: 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]);
1161: #else
1162: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1163: #endif
1164: }
1165: }
1166: #endif
1168: if (mat->assembled) {
1169: mat->was_assembled = PETSC_TRUE;
1170: mat->assembled = PETSC_FALSE;
1171: }
1172: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1173: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1174: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1175: #if defined(PETSC_HAVE_CUSP)
1176: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1177: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1178: }
1179: #endif
1180: #if defined(PETSC_HAVE_VIENNACL)
1181: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1182: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1183: }
1184: #endif
1185: return(0);
1186: }
1191: /*@
1192: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1193: values into a matrix
1195: Not Collective
1197: Input Parameters:
1198: + mat - the matrix
1199: . row - the (block) row to set
1200: - v - a logically two-dimensional array of values
1202: Notes:
1203: By the values, v, are column-oriented (for the block version) and sorted
1205: All the nonzeros in the row must be provided
1207: The matrix must have previously had its column indices set
1209: The row must belong to this process
1211: Level: intermediate
1213: Concepts: matrices^putting entries in
1215: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1216: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1217: @*/
1218: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1219: {
1221: PetscInt globalrow;
1227: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1228: MatSetValuesRow(mat,globalrow,v);
1229: #if defined(PETSC_HAVE_CUSP)
1230: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1231: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1232: }
1233: #endif
1234: #if defined(PETSC_HAVE_VIENNACL)
1235: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1236: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1237: }
1238: #endif
1239: return(0);
1240: }
1244: /*@
1245: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1246: values into a matrix
1248: Not Collective
1250: Input Parameters:
1251: + mat - the matrix
1252: . row - the (block) row to set
1253: - v - a logically two-dimensional array of values
1255: Notes:
1256: The values, v, are column-oriented for the block version.
1258: All the nonzeros in the row must be provided
1260: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1262: The row must belong to this process
1264: Level: advanced
1266: Concepts: matrices^putting entries in
1268: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1269: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1270: @*/
1271: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1272: {
1278: MatCheckPreallocated(mat,1);
1280: #if defined(PETSC_USE_DEBUG)
1281: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1282: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1283: #endif
1284: mat->insertmode = INSERT_VALUES;
1286: if (mat->assembled) {
1287: mat->was_assembled = PETSC_TRUE;
1288: mat->assembled = PETSC_FALSE;
1289: }
1290: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1291: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1292: (*mat->ops->setvaluesrow)(mat,row,v);
1293: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1294: #if defined(PETSC_HAVE_CUSP)
1295: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1296: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1297: }
1298: #endif
1299: #if defined(PETSC_HAVE_VIENNACL)
1300: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1301: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1302: }
1303: #endif
1304: return(0);
1305: }
1309: /*@
1310: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1311: Using structured grid indexing
1313: Not Collective
1315: Input Parameters:
1316: + mat - the matrix
1317: . m - number of rows being entered
1318: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1319: . n - number of columns being entered
1320: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1321: . v - a logically two-dimensional array of values
1322: - addv - either ADD_VALUES or INSERT_VALUES, where
1323: ADD_VALUES adds values to any existing entries, and
1324: INSERT_VALUES replaces existing entries with new values
1326: Notes:
1327: By default the values, v, are row-oriented. See MatSetOption() for other options.
1329: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1330: options cannot be mixed without intervening calls to the assembly
1331: routines.
1333: The grid coordinates are across the entire grid, not just the local portion
1335: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1336: as well as in C.
1338: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1340: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1341: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1343: The columns and rows in the stencil passed in MUST be contained within the
1344: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1345: if you create a DMDA with an overlap of one grid level and on a particular process its first
1346: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1347: first i index you can use in your column and row indices in MatSetStencil() is 5.
1349: In Fortran idxm and idxn should be declared as
1350: $ MatStencil idxm(4,m),idxn(4,n)
1351: and the values inserted using
1352: $ idxm(MatStencil_i,1) = i
1353: $ idxm(MatStencil_j,1) = j
1354: $ idxm(MatStencil_k,1) = k
1355: $ idxm(MatStencil_c,1) = c
1356: etc
1358: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1359: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1360: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1361: DM_BOUNDARY_PERIODIC boundary type.
1363: 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
1364: a single value per point) you can skip filling those indices.
1366: Inspired by the structured grid interface to the HYPRE package
1367: (http://www.llnl.gov/CASC/hypre)
1369: Efficiency Alert:
1370: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1371: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1373: Level: beginner
1375: Concepts: matrices^putting entries in
1377: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1378: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1379: @*/
1380: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1381: {
1383: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1384: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1385: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1388: if (!m || !n) return(0); /* no values to insert */
1395: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1396: jdxm = buf; jdxn = buf+m;
1397: } else {
1398: PetscMalloc2(m,&bufm,n,&bufn);
1399: jdxm = bufm; jdxn = bufn;
1400: }
1401: for (i=0; i<m; i++) {
1402: for (j=0; j<3-sdim; j++) dxm++;
1403: tmp = *dxm++ - starts[0];
1404: for (j=0; j<dim-1; j++) {
1405: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1406: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1407: }
1408: if (mat->stencil.noc) dxm++;
1409: jdxm[i] = tmp;
1410: }
1411: for (i=0; i<n; i++) {
1412: for (j=0; j<3-sdim; j++) dxn++;
1413: tmp = *dxn++ - starts[0];
1414: for (j=0; j<dim-1; j++) {
1415: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1416: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1417: }
1418: if (mat->stencil.noc) dxn++;
1419: jdxn[i] = tmp;
1420: }
1421: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1422: PetscFree2(bufm,bufn);
1423: return(0);
1424: }
1428: /*@
1429: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1430: Using structured grid indexing
1432: Not Collective
1434: Input Parameters:
1435: + mat - the matrix
1436: . m - number of rows being entered
1437: . idxm - grid coordinates for matrix rows being entered
1438: . n - number of columns being entered
1439: . idxn - grid coordinates for matrix columns being entered
1440: . v - a logically two-dimensional array of values
1441: - addv - either ADD_VALUES or INSERT_VALUES, where
1442: ADD_VALUES adds values to any existing entries, and
1443: INSERT_VALUES replaces existing entries with new values
1445: Notes:
1446: By default the values, v, are row-oriented and unsorted.
1447: See MatSetOption() for other options.
1449: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1450: options cannot be mixed without intervening calls to the assembly
1451: routines.
1453: The grid coordinates are across the entire grid, not just the local portion
1455: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1456: as well as in C.
1458: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1460: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1461: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1463: The columns and rows in the stencil passed in MUST be contained within the
1464: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1465: if you create a DMDA with an overlap of one grid level and on a particular process its first
1466: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1467: first i index you can use in your column and row indices in MatSetStencil() is 5.
1469: In Fortran idxm and idxn should be declared as
1470: $ MatStencil idxm(4,m),idxn(4,n)
1471: and the values inserted using
1472: $ idxm(MatStencil_i,1) = i
1473: $ idxm(MatStencil_j,1) = j
1474: $ idxm(MatStencil_k,1) = k
1475: etc
1477: Negative indices may be passed in idxm and idxn, these rows and columns are
1478: simply ignored. This allows easily inserting element stiffness matrices
1479: with homogeneous Dirchlet boundary conditions that you don't want represented
1480: in the matrix.
1482: Inspired by the structured grid interface to the HYPRE package
1483: (http://www.llnl.gov/CASC/hypre)
1485: Level: beginner
1487: Concepts: matrices^putting entries in
1489: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1490: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1491: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1492: @*/
1493: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1494: {
1496: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1497: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1498: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1501: if (!m || !n) return(0); /* no values to insert */
1508: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1509: jdxm = buf; jdxn = buf+m;
1510: } else {
1511: PetscMalloc2(m,&bufm,n,&bufn);
1512: jdxm = bufm; jdxn = bufn;
1513: }
1514: for (i=0; i<m; i++) {
1515: for (j=0; j<3-sdim; j++) dxm++;
1516: tmp = *dxm++ - starts[0];
1517: for (j=0; j<sdim-1; j++) {
1518: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1519: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1520: }
1521: dxm++;
1522: jdxm[i] = tmp;
1523: }
1524: for (i=0; i<n; i++) {
1525: for (j=0; j<3-sdim; j++) dxn++;
1526: tmp = *dxn++ - starts[0];
1527: for (j=0; j<sdim-1; j++) {
1528: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1529: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1530: }
1531: dxn++;
1532: jdxn[i] = tmp;
1533: }
1534: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1535: PetscFree2(bufm,bufn);
1536: #if defined(PETSC_HAVE_CUSP)
1537: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1538: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1539: }
1540: #endif
1541: #if defined(PETSC_HAVE_VIENNACL)
1542: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1543: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1544: }
1545: #endif
1546: return(0);
1547: }
1551: /*@
1552: MatSetStencil - Sets the grid information for setting values into a matrix via
1553: MatSetValuesStencil()
1555: Not Collective
1557: Input Parameters:
1558: + mat - the matrix
1559: . dim - dimension of the grid 1, 2, or 3
1560: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1561: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1562: - dof - number of degrees of freedom per node
1565: Inspired by the structured grid interface to the HYPRE package
1566: (www.llnl.gov/CASC/hyper)
1568: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1569: user.
1571: Level: beginner
1573: Concepts: matrices^putting entries in
1575: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1576: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1577: @*/
1578: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1579: {
1580: PetscInt i;
1587: mat->stencil.dim = dim + (dof > 1);
1588: for (i=0; i<dim; i++) {
1589: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1590: mat->stencil.starts[i] = starts[dim-i-1];
1591: }
1592: mat->stencil.dims[dim] = dof;
1593: mat->stencil.starts[dim] = 0;
1594: mat->stencil.noc = (PetscBool)(dof == 1);
1595: return(0);
1596: }
1600: /*@
1601: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1603: Not Collective
1605: Input Parameters:
1606: + mat - the matrix
1607: . v - a logically two-dimensional array of values
1608: . m, idxm - the number of block rows and their global block indices
1609: . n, idxn - the number of block columns and their global block indices
1610: - addv - either ADD_VALUES or INSERT_VALUES, where
1611: ADD_VALUES adds values to any existing entries, and
1612: INSERT_VALUES replaces existing entries with new values
1614: Notes:
1615: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1616: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1618: The m and n count the NUMBER of blocks in the row direction and column direction,
1619: NOT the total number of rows/columns; for example, if the block size is 2 and
1620: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1621: The values in idxm would be 1 2; that is the first index for each block divided by
1622: the block size.
1624: Note that you must call MatSetBlockSize() when constructing this matrix (before
1625: preallocating it).
1627: By default the values, v, are row-oriented, so the layout of
1628: v is the same as for MatSetValues(). See MatSetOption() for other options.
1630: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1631: options cannot be mixed without intervening calls to the assembly
1632: routines.
1634: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1635: as well as in C.
1637: Negative indices may be passed in idxm and idxn, these rows and columns are
1638: simply ignored. This allows easily inserting element stiffness matrices
1639: with homogeneous Dirchlet boundary conditions that you don't want represented
1640: in the matrix.
1642: Each time an entry is set within a sparse matrix via MatSetValues(),
1643: internal searching must be done to determine where to place the the
1644: data in the matrix storage space. By instead inserting blocks of
1645: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1646: reduced.
1648: Example:
1649: $ Suppose m=n=2 and block size(bs) = 2 The array is
1650: $
1651: $ 1 2 | 3 4
1652: $ 5 6 | 7 8
1653: $ - - - | - - -
1654: $ 9 10 | 11 12
1655: $ 13 14 | 15 16
1656: $
1657: $ v[] should be passed in like
1658: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1659: $
1660: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1661: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1663: Level: intermediate
1665: Concepts: matrices^putting entries in blocked
1667: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1668: @*/
1669: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1670: {
1676: if (!m || !n) return(0); /* no values to insert */
1680: MatCheckPreallocated(mat,1);
1681: if (mat->insertmode == NOT_SET_VALUES) {
1682: mat->insertmode = addv;
1683: }
1684: #if defined(PETSC_USE_DEBUG)
1685: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1686: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1687: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1688: #endif
1690: if (mat->assembled) {
1691: mat->was_assembled = PETSC_TRUE;
1692: mat->assembled = PETSC_FALSE;
1693: }
1694: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1695: if (mat->ops->setvaluesblocked) {
1696: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1697: } else {
1698: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1699: PetscInt i,j,bs,cbs;
1700: MatGetBlockSizes(mat,&bs,&cbs);
1701: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1702: iidxm = buf; iidxn = buf + m*bs;
1703: } else {
1704: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1705: iidxm = bufr; iidxn = bufc;
1706: }
1707: for (i=0; i<m; i++) {
1708: for (j=0; j<bs; j++) {
1709: iidxm[i*bs+j] = bs*idxm[i] + j;
1710: }
1711: }
1712: for (i=0; i<n; i++) {
1713: for (j=0; j<cbs; j++) {
1714: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1715: }
1716: }
1717: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1718: PetscFree2(bufr,bufc);
1719: }
1720: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1721: #if defined(PETSC_HAVE_CUSP)
1722: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1723: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1724: }
1725: #endif
1726: #if defined(PETSC_HAVE_VIENNACL)
1727: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1728: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1729: }
1730: #endif
1731: return(0);
1732: }
1736: /*@
1737: MatGetValues - Gets a block of values from a matrix.
1739: Not Collective; currently only returns a local block
1741: Input Parameters:
1742: + mat - the matrix
1743: . v - a logically two-dimensional array for storing the values
1744: . m, idxm - the number of rows and their global indices
1745: - n, idxn - the number of columns and their global indices
1747: Notes:
1748: The user must allocate space (m*n PetscScalars) for the values, v.
1749: The values, v, are then returned in a row-oriented format,
1750: analogous to that used by default in MatSetValues().
1752: MatGetValues() uses 0-based row and column numbers in
1753: Fortran as well as in C.
1755: MatGetValues() requires that the matrix has been assembled
1756: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1757: MatSetValues() and MatGetValues() CANNOT be made in succession
1758: without intermediate matrix assembly.
1760: Negative row or column indices will be ignored and those locations in v[] will be
1761: left unchanged.
1763: Level: advanced
1765: Concepts: matrices^accessing values
1767: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1768: @*/
1769: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1770: {
1776: if (!m || !n) return(0);
1780: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1781: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1782: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1783: MatCheckPreallocated(mat,1);
1785: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1786: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1787: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1788: return(0);
1789: }
1793: /*@
1794: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1795: the same size. Currently, this can only be called once and creates the given matrix.
1797: Not Collective
1799: Input Parameters:
1800: + mat - the matrix
1801: . nb - the number of blocks
1802: . bs - the number of rows (and columns) in each block
1803: . rows - a concatenation of the rows for each block
1804: - v - a concatenation of logically two-dimensional arrays of values
1806: Notes:
1807: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1809: Level: advanced
1811: Concepts: matrices^putting entries in
1813: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1814: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1815: @*/
1816: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1817: {
1825: #if defined(PETSC_USE_DEBUG)
1826: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1827: #endif
1829: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1830: if (mat->ops->setvaluesbatch) {
1831: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1832: } else {
1833: PetscInt b;
1834: for (b = 0; b < nb; ++b) {
1835: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1836: }
1837: }
1838: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1839: return(0);
1840: }
1844: /*@
1845: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1846: the routine MatSetValuesLocal() to allow users to insert matrix entries
1847: using a local (per-processor) numbering.
1849: Not Collective
1851: Input Parameters:
1852: + x - the matrix
1853: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1854: - cmapping - column mapping
1856: Level: intermediate
1858: Concepts: matrices^local to global mapping
1859: Concepts: local to global mapping^for matrices
1861: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1862: @*/
1863: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1864: {
1873: if (x->ops->setlocaltoglobalmapping) {
1874: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1875: } else {
1876: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1877: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1878: }
1879: return(0);
1880: }
1885: /*@
1886: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1888: Not Collective
1890: Input Parameters:
1891: . A - the matrix
1893: Output Parameters:
1894: + rmapping - row mapping
1895: - cmapping - column mapping
1897: Level: advanced
1899: Concepts: matrices^local to global mapping
1900: Concepts: local to global mapping^for matrices
1902: .seealso: MatSetValuesLocal()
1903: @*/
1904: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1905: {
1911: if (rmapping) *rmapping = A->rmap->mapping;
1912: if (cmapping) *cmapping = A->cmap->mapping;
1913: return(0);
1914: }
1918: /*@
1919: MatGetLayouts - Gets the PetscLayout objects for rows and columns
1921: Not Collective
1923: Input Parameters:
1924: . A - the matrix
1926: Output Parameters:
1927: + rmap - row layout
1928: - cmap - column layout
1930: Level: advanced
1932: .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping()
1933: @*/
1934: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1935: {
1941: if (rmap) *rmap = A->rmap;
1942: if (cmap) *cmap = A->cmap;
1943: return(0);
1944: }
1948: /*@
1949: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1950: using a local ordering of the nodes.
1952: Not Collective
1954: Input Parameters:
1955: + x - the matrix
1956: . nrow, irow - number of rows and their local indices
1957: . ncol, icol - number of columns and their local indices
1958: . y - a logically two-dimensional array of values
1959: - addv - either INSERT_VALUES or ADD_VALUES, where
1960: ADD_VALUES adds values to any existing entries, and
1961: INSERT_VALUES replaces existing entries with new values
1963: Notes:
1964: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1965: MatSetUp() before using this routine
1967: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1969: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1970: options cannot be mixed without intervening calls to the assembly
1971: routines.
1973: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1974: MUST be called after all calls to MatSetValuesLocal() have been completed.
1976: Level: intermediate
1978: Concepts: matrices^putting entries in with local numbering
1980: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1981: MatSetValueLocal()
1982: @*/
1983: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1984: {
1990: MatCheckPreallocated(mat,1);
1991: if (!nrow || !ncol) return(0); /* no values to insert */
1995: if (mat->insertmode == NOT_SET_VALUES) {
1996: mat->insertmode = addv;
1997: }
1998: #if defined(PETSC_USE_DEBUG)
1999: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2000: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2001: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2002: #endif
2004: if (mat->assembled) {
2005: mat->was_assembled = PETSC_TRUE;
2006: mat->assembled = PETSC_FALSE;
2007: }
2008: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2009: if (mat->ops->setvalueslocal) {
2010: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2011: } else {
2012: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2013: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2014: irowm = buf; icolm = buf+nrow;
2015: } else {
2016: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2017: irowm = bufr; icolm = bufc;
2018: }
2019: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2020: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2021: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2022: PetscFree2(bufr,bufc);
2023: }
2024: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2025: #if defined(PETSC_HAVE_CUSP)
2026: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2027: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2028: }
2029: #endif
2030: #if defined(PETSC_HAVE_VIENNACL)
2031: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2032: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2033: }
2034: #endif
2035: return(0);
2036: }
2040: /*@
2041: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2042: using a local ordering of the nodes a block at a time.
2044: Not Collective
2046: Input Parameters:
2047: + x - the matrix
2048: . nrow, irow - number of rows and their local indices
2049: . ncol, icol - number of columns and their local indices
2050: . y - a logically two-dimensional array of values
2051: - addv - either INSERT_VALUES or ADD_VALUES, where
2052: ADD_VALUES adds values to any existing entries, and
2053: INSERT_VALUES replaces existing entries with new values
2055: Notes:
2056: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2057: MatSetUp() before using this routine
2059: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2060: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2062: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2063: options cannot be mixed without intervening calls to the assembly
2064: routines.
2066: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2067: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2069: Level: intermediate
2071: Concepts: matrices^putting blocked values in with local numbering
2073: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2074: MatSetValuesLocal(), MatSetValuesBlocked()
2075: @*/
2076: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2077: {
2083: MatCheckPreallocated(mat,1);
2084: if (!nrow || !ncol) return(0); /* no values to insert */
2088: if (mat->insertmode == NOT_SET_VALUES) {
2089: mat->insertmode = addv;
2090: }
2091: #if defined(PETSC_USE_DEBUG)
2092: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2093: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2094: 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);
2095: #endif
2097: if (mat->assembled) {
2098: mat->was_assembled = PETSC_TRUE;
2099: mat->assembled = PETSC_FALSE;
2100: }
2101: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2102: if (mat->ops->setvaluesblockedlocal) {
2103: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2104: } else {
2105: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2106: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2107: irowm = buf; icolm = buf + nrow;
2108: } else {
2109: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2110: irowm = bufr; icolm = bufc;
2111: }
2112: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2113: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2114: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2115: PetscFree2(bufr,bufc);
2116: }
2117: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2118: #if defined(PETSC_HAVE_CUSP)
2119: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2120: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2121: }
2122: #endif
2123: #if defined(PETSC_HAVE_VIENNACL)
2124: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2125: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2126: }
2127: #endif
2128: return(0);
2129: }
2133: /*@
2134: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2136: Collective on Mat and Vec
2138: Input Parameters:
2139: + mat - the matrix
2140: - x - the vector to be multiplied
2142: Output Parameters:
2143: . y - the result
2145: Notes:
2146: The vectors x and y cannot be the same. I.e., one cannot
2147: call MatMult(A,y,y).
2149: Level: developer
2151: Concepts: matrix-vector product
2153: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2154: @*/
2155: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2156: {
2165: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2166: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2167: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2168: MatCheckPreallocated(mat,1);
2170: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2171: (*mat->ops->multdiagonalblock)(mat,x,y);
2172: PetscObjectStateIncrease((PetscObject)y);
2173: return(0);
2174: }
2176: /* --------------------------------------------------------*/
2179: /*@
2180: MatMult - Computes the matrix-vector product, y = Ax.
2182: Neighbor-wise Collective on Mat and Vec
2184: Input Parameters:
2185: + mat - the matrix
2186: - x - the vector to be multiplied
2188: Output Parameters:
2189: . y - the result
2191: Notes:
2192: The vectors x and y cannot be the same. I.e., one cannot
2193: call MatMult(A,y,y).
2195: Level: beginner
2197: Concepts: matrix-vector product
2199: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2200: @*/
2201: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2202: {
2210: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2211: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2212: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2213: #if !defined(PETSC_HAVE_CONSTRAINTS)
2214: 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);
2215: 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);
2216: 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);
2217: #endif
2218: VecLocked(y,3);
2219: if (mat->erroriffpe) {VecValidValues(x,2,PETSC_TRUE);}
2220: MatCheckPreallocated(mat,1);
2222: VecLockPush(x);
2223: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2224: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2225: (*mat->ops->mult)(mat,x,y);
2226: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2227: if (mat->erroriffpe) {VecValidValues(y,3,PETSC_FALSE);}
2228: VecLockPop(x);
2229: return(0);
2230: }
2234: /*@
2235: MatMultTranspose - Computes matrix transpose times a vector.
2237: Neighbor-wise Collective on Mat and Vec
2239: Input Parameters:
2240: + mat - the matrix
2241: - x - the vector to be multilplied
2243: Output Parameters:
2244: . y - the result
2246: Notes:
2247: The vectors x and y cannot be the same. I.e., one cannot
2248: call MatMultTranspose(A,y,y).
2250: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2251: use MatMultHermitianTranspose()
2253: Level: beginner
2255: Concepts: matrix vector product^transpose
2257: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2258: @*/
2259: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2260: {
2269: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2270: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2271: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2272: #if !defined(PETSC_HAVE_CONSTRAINTS)
2273: 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);
2274: 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);
2275: #endif
2276: if (mat->erroriffpe) {VecValidValues(x,2,PETSC_TRUE);}
2277: MatCheckPreallocated(mat,1);
2279: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2280: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2281: VecLockPush(x);
2282: (*mat->ops->multtranspose)(mat,x,y);
2283: VecLockPop(x);
2284: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2285: PetscObjectStateIncrease((PetscObject)y);
2286: if (mat->erroriffpe) {VecValidValues(y,3,PETSC_FALSE);}
2287: return(0);
2288: }
2292: /*@
2293: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2295: Neighbor-wise Collective on Mat and Vec
2297: Input Parameters:
2298: + mat - the matrix
2299: - x - the vector to be multilplied
2301: Output Parameters:
2302: . y - the result
2304: Notes:
2305: The vectors x and y cannot be the same. I.e., one cannot
2306: call MatMultHermitianTranspose(A,y,y).
2308: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2310: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2312: Level: beginner
2314: Concepts: matrix vector product^transpose
2316: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2317: @*/
2318: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2319: {
2321: Vec w;
2329: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2330: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2331: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2332: #if !defined(PETSC_HAVE_CONSTRAINTS)
2333: 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);
2334: 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);
2335: #endif
2336: MatCheckPreallocated(mat,1);
2338: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2339: if (mat->ops->multhermitiantranspose) {
2340: VecLockPush(x);
2341: (*mat->ops->multhermitiantranspose)(mat,x,y);
2342: VecLockPop(x);
2343: } else {
2344: VecDuplicate(x,&w);
2345: VecCopy(x,w);
2346: VecConjugate(w);
2347: MatMultTranspose(mat,w,y);
2348: VecDestroy(&w);
2349: VecConjugate(y);
2350: }
2351: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2352: PetscObjectStateIncrease((PetscObject)y);
2353: return(0);
2354: }
2358: /*@
2359: MatMultAdd - Computes v3 = v2 + A * v1.
2361: Neighbor-wise Collective on Mat and Vec
2363: Input Parameters:
2364: + mat - the matrix
2365: - v1, v2 - the vectors
2367: Output Parameters:
2368: . v3 - the result
2370: Notes:
2371: The vectors v1 and v3 cannot be the same. I.e., one cannot
2372: call MatMultAdd(A,v1,v2,v1).
2374: Level: beginner
2376: Concepts: matrix vector product^addition
2378: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2379: @*/
2380: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2381: {
2391: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2392: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2393: 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);
2394: /* 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);
2395: 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); */
2396: 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);
2397: 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);
2398: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2399: MatCheckPreallocated(mat,1);
2401: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2402: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2403: VecLockPush(v1);
2404: (*mat->ops->multadd)(mat,v1,v2,v3);
2405: VecLockPop(v1);
2406: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2407: PetscObjectStateIncrease((PetscObject)v3);
2408: return(0);
2409: }
2413: /*@
2414: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2416: Neighbor-wise Collective on Mat and Vec
2418: Input Parameters:
2419: + mat - the matrix
2420: - v1, v2 - the vectors
2422: Output Parameters:
2423: . v3 - the result
2425: Notes:
2426: The vectors v1 and v3 cannot be the same. I.e., one cannot
2427: call MatMultTransposeAdd(A,v1,v2,v1).
2429: Level: beginner
2431: Concepts: matrix vector product^transpose and addition
2433: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2434: @*/
2435: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2436: {
2446: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2447: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2448: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2449: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2450: 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);
2451: 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);
2452: 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);
2453: MatCheckPreallocated(mat,1);
2455: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2456: VecLockPush(v1);
2457: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2458: VecLockPop(v1);
2459: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2460: PetscObjectStateIncrease((PetscObject)v3);
2461: return(0);
2462: }
2466: /*@
2467: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2469: Neighbor-wise Collective on Mat and Vec
2471: Input Parameters:
2472: + mat - the matrix
2473: - v1, v2 - the vectors
2475: Output Parameters:
2476: . v3 - the result
2478: Notes:
2479: The vectors v1 and v3 cannot be the same. I.e., one cannot
2480: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2482: Level: beginner
2484: Concepts: matrix vector product^transpose and addition
2486: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2487: @*/
2488: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2489: {
2499: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2500: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2501: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2502: 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);
2503: 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);
2504: 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);
2505: MatCheckPreallocated(mat,1);
2507: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2508: VecLockPush(v1);
2509: if (mat->ops->multhermitiantransposeadd) {
2510: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2511: } else {
2512: Vec w,z;
2513: VecDuplicate(v1,&w);
2514: VecCopy(v1,w);
2515: VecConjugate(w);
2516: VecDuplicate(v3,&z);
2517: MatMultTranspose(mat,w,z);
2518: VecDestroy(&w);
2519: VecConjugate(z);
2520: VecWAXPY(v3,1.0,v2,z);
2521: VecDestroy(&z);
2522: }
2523: VecLockPop(v1);
2524: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2525: PetscObjectStateIncrease((PetscObject)v3);
2526: return(0);
2527: }
2531: /*@
2532: MatMultConstrained - The inner multiplication routine for a
2533: constrained matrix P^T A P.
2535: Neighbor-wise Collective on Mat and Vec
2537: Input Parameters:
2538: + mat - the matrix
2539: - x - the vector to be multilplied
2541: Output Parameters:
2542: . y - the result
2544: Notes:
2545: The vectors x and y cannot be the same. I.e., one cannot
2546: call MatMult(A,y,y).
2548: Level: beginner
2550: .keywords: matrix, multiply, matrix-vector product, constraint
2551: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2552: @*/
2553: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2554: {
2561: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2562: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2563: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2564: 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);
2565: 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);
2566: 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);
2568: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2569: VecLockPush(x);
2570: (*mat->ops->multconstrained)(mat,x,y);
2571: VecLockPop(x);
2572: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2573: PetscObjectStateIncrease((PetscObject)y);
2574: return(0);
2575: }
2579: /*@
2580: MatMultTransposeConstrained - The inner multiplication routine for a
2581: constrained matrix P^T A^T P.
2583: Neighbor-wise Collective on Mat and Vec
2585: Input Parameters:
2586: + mat - the matrix
2587: - x - the vector to be multilplied
2589: Output Parameters:
2590: . y - the result
2592: Notes:
2593: The vectors x and y cannot be the same. I.e., one cannot
2594: call MatMult(A,y,y).
2596: Level: beginner
2598: .keywords: matrix, multiply, matrix-vector product, constraint
2599: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2600: @*/
2601: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2602: {
2609: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2610: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2611: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2612: 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);
2613: 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);
2615: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2616: (*mat->ops->multtransposeconstrained)(mat,x,y);
2617: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2618: PetscObjectStateIncrease((PetscObject)y);
2619: return(0);
2620: }
2624: /*@C
2625: MatGetFactorType - gets the type of factorization it is
2627: Note Collective
2628: as the flag
2630: Input Parameters:
2631: . mat - the matrix
2633: Output Parameters:
2634: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2636: Level: intermediate
2638: .seealso: MatFactorType, MatGetFactor()
2639: @*/
2640: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2641: {
2645: *t = mat->factortype;
2646: return(0);
2647: }
2649: /* ------------------------------------------------------------*/
2652: /*@C
2653: MatGetInfo - Returns information about matrix storage (number of
2654: nonzeros, memory, etc.).
2656: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2658: Input Parameters:
2659: . mat - the matrix
2661: Output Parameters:
2662: + flag - flag indicating the type of parameters to be returned
2663: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2664: MAT_GLOBAL_SUM - sum over all processors)
2665: - info - matrix information context
2667: Notes:
2668: The MatInfo context contains a variety of matrix data, including
2669: number of nonzeros allocated and used, number of mallocs during
2670: matrix assembly, etc. Additional information for factored matrices
2671: is provided (such as the fill ratio, number of mallocs during
2672: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2673: when using the runtime options
2674: $ -info -mat_view ::ascii_info
2676: Example for C/C++ Users:
2677: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2678: data within the MatInfo context. For example,
2679: .vb
2680: MatInfo info;
2681: Mat A;
2682: double mal, nz_a, nz_u;
2684: MatGetInfo(A,MAT_LOCAL,&info);
2685: mal = info.mallocs;
2686: nz_a = info.nz_allocated;
2687: .ve
2689: Example for Fortran Users:
2690: Fortran users should declare info as a double precision
2691: array of dimension MAT_INFO_SIZE, and then extract the parameters
2692: of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2693: a complete list of parameter names.
2694: .vb
2695: double precision info(MAT_INFO_SIZE)
2696: double precision mal, nz_a
2697: Mat A
2698: integer ierr
2700: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2701: mal = info(MAT_INFO_MALLOCS)
2702: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2703: .ve
2705: Level: intermediate
2707: Concepts: matrices^getting information on
2709: Developer Note: fortran interface is not autogenerated as the f90
2710: interface defintion cannot be generated correctly [due to MatInfo]
2712: .seealso: MatStashGetInfo()
2714: @*/
2715: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2716: {
2723: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2724: MatCheckPreallocated(mat,1);
2725: (*mat->ops->getinfo)(mat,flag,info);
2726: return(0);
2727: }
2729: /* ----------------------------------------------------------*/
2733: /*@C
2734: MatLUFactor - Performs in-place LU factorization of matrix.
2736: Collective on Mat
2738: Input Parameters:
2739: + mat - the matrix
2740: . row - row permutation
2741: . col - column permutation
2742: - info - options for factorization, includes
2743: $ fill - expected fill as ratio of original fill.
2744: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2745: $ Run with the option -info to determine an optimal value to use
2747: Notes:
2748: Most users should employ the simplified KSP interface for linear solvers
2749: instead of working directly with matrix algebra routines such as this.
2750: See, e.g., KSPCreate().
2752: This changes the state of the matrix to a factored matrix; it cannot be used
2753: for example with MatSetValues() unless one first calls MatSetUnfactored().
2755: Level: developer
2757: Concepts: matrices^LU factorization
2759: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2760: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2762: Developer Note: fortran interface is not autogenerated as the f90
2763: interface defintion cannot be generated correctly [due to MatFactorInfo]
2765: @*/
2766: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2767: {
2769: MatFactorInfo tinfo;
2777: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2778: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2779: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2780: MatCheckPreallocated(mat,1);
2781: if (!info) {
2782: MatFactorInfoInitialize(&tinfo);
2783: info = &tinfo;
2784: }
2786: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2787: (*mat->ops->lufactor)(mat,row,col,info);
2788: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2789: PetscObjectStateIncrease((PetscObject)mat);
2790: return(0);
2791: }
2795: /*@C
2796: MatILUFactor - Performs in-place ILU factorization of matrix.
2798: Collective on Mat
2800: Input Parameters:
2801: + mat - the matrix
2802: . row - row permutation
2803: . col - column permutation
2804: - info - structure containing
2805: $ levels - number of levels of fill.
2806: $ expected fill - as ratio of original fill.
2807: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2808: missing diagonal entries)
2810: Notes:
2811: Probably really in-place only when level of fill is zero, otherwise allocates
2812: new space to store factored matrix and deletes previous memory.
2814: Most users should employ the simplified KSP interface for linear solvers
2815: instead of working directly with matrix algebra routines such as this.
2816: See, e.g., KSPCreate().
2818: Level: developer
2820: Concepts: matrices^ILU factorization
2822: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2824: Developer Note: fortran interface is not autogenerated as the f90
2825: interface defintion cannot be generated correctly [due to MatFactorInfo]
2827: @*/
2828: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2829: {
2838: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2839: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2840: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2841: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2842: MatCheckPreallocated(mat,1);
2844: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2845: (*mat->ops->ilufactor)(mat,row,col,info);
2846: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2847: PetscObjectStateIncrease((PetscObject)mat);
2848: return(0);
2849: }
2853: /*@C
2854: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2855: Call this routine before calling MatLUFactorNumeric().
2857: Collective on Mat
2859: Input Parameters:
2860: + fact - the factor matrix obtained with MatGetFactor()
2861: . mat - the matrix
2862: . row, col - row and column permutations
2863: - info - options for factorization, includes
2864: $ fill - expected fill as ratio of original fill.
2865: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2866: $ Run with the option -info to determine an optimal value to use
2869: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2871: Most users should employ the simplified KSP interface for linear solvers
2872: instead of working directly with matrix algebra routines such as this.
2873: See, e.g., KSPCreate().
2875: Level: developer
2877: Concepts: matrices^LU symbolic factorization
2879: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2881: Developer Note: fortran interface is not autogenerated as the f90
2882: interface defintion cannot be generated correctly [due to MatFactorInfo]
2884: @*/
2885: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2886: {
2896: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2897: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2898: if (!(fact)->ops->lufactorsymbolic) {
2899: const MatSolverPackage spackage;
2900: MatFactorGetSolverPackage(fact,&spackage);
2901: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2902: }
2903: MatCheckPreallocated(mat,2);
2905: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2906: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2907: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2908: PetscObjectStateIncrease((PetscObject)fact);
2909: return(0);
2910: }
2914: /*@C
2915: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2916: Call this routine after first calling MatLUFactorSymbolic().
2918: Collective on Mat
2920: Input Parameters:
2921: + fact - the factor matrix obtained with MatGetFactor()
2922: . mat - the matrix
2923: - info - options for factorization
2925: Notes:
2926: See MatLUFactor() for in-place factorization. See
2927: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2929: Most users should employ the simplified KSP interface for linear solvers
2930: instead of working directly with matrix algebra routines such as this.
2931: See, e.g., KSPCreate().
2933: Level: developer
2935: Concepts: matrices^LU numeric factorization
2937: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2939: Developer Note: fortran interface is not autogenerated as the f90
2940: interface defintion cannot be generated correctly [due to MatFactorInfo]
2942: @*/
2943: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2944: {
2952: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2953: 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);
2955: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2956: MatCheckPreallocated(mat,2);
2957: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2958: (fact->ops->lufactornumeric)(fact,mat,info);
2959: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2960: MatViewFromOptions(fact,NULL,"-mat_factor_view");
2961: PetscObjectStateIncrease((PetscObject)fact);
2962: return(0);
2963: }
2967: /*@C
2968: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2969: symmetric matrix.
2971: Collective on Mat
2973: Input Parameters:
2974: + mat - the matrix
2975: . perm - row and column permutations
2976: - f - expected fill as ratio of original fill
2978: Notes:
2979: See MatLUFactor() for the nonsymmetric case. See also
2980: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2982: Most users should employ the simplified KSP interface for linear solvers
2983: instead of working directly with matrix algebra routines such as this.
2984: See, e.g., KSPCreate().
2986: Level: developer
2988: Concepts: matrices^Cholesky factorization
2990: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2991: MatGetOrdering()
2993: Developer Note: fortran interface is not autogenerated as the f90
2994: interface defintion cannot be generated correctly [due to MatFactorInfo]
2996: @*/
2997: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2998: {
3006: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3007: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3008: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3009: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3010: MatCheckPreallocated(mat,1);
3012: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3013: (*mat->ops->choleskyfactor)(mat,perm,info);
3014: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3015: PetscObjectStateIncrease((PetscObject)mat);
3016: return(0);
3017: }
3021: /*@C
3022: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3023: of a symmetric matrix.
3025: Collective on Mat
3027: Input Parameters:
3028: + fact - the factor matrix obtained with MatGetFactor()
3029: . mat - the matrix
3030: . perm - row and column permutations
3031: - info - options for factorization, includes
3032: $ fill - expected fill as ratio of original fill.
3033: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3034: $ Run with the option -info to determine an optimal value to use
3036: Notes:
3037: See MatLUFactorSymbolic() for the nonsymmetric case. See also
3038: MatCholeskyFactor() and MatCholeskyFactorNumeric().
3040: Most users should employ the simplified KSP interface for linear solvers
3041: instead of working directly with matrix algebra routines such as this.
3042: See, e.g., KSPCreate().
3044: Level: developer
3046: Concepts: matrices^Cholesky symbolic factorization
3048: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3049: MatGetOrdering()
3051: Developer Note: fortran interface is not autogenerated as the f90
3052: interface defintion cannot be generated correctly [due to MatFactorInfo]
3054: @*/
3055: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3056: {
3065: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3066: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3067: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3068: if (!(fact)->ops->choleskyfactorsymbolic) {
3069: const MatSolverPackage spackage;
3070: MatFactorGetSolverPackage(fact,&spackage);
3071: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3072: }
3073: MatCheckPreallocated(mat,2);
3075: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3076: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3077: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3078: PetscObjectStateIncrease((PetscObject)fact);
3079: return(0);
3080: }
3084: /*@C
3085: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3086: of a symmetric matrix. Call this routine after first calling
3087: MatCholeskyFactorSymbolic().
3089: Collective on Mat
3091: Input Parameters:
3092: + fact - the factor matrix obtained with MatGetFactor()
3093: . mat - the initial matrix
3094: . info - options for factorization
3095: - fact - the symbolic factor of mat
3098: Notes:
3099: Most users should employ the simplified KSP interface for linear solvers
3100: instead of working directly with matrix algebra routines such as this.
3101: See, e.g., KSPCreate().
3103: Level: developer
3105: Concepts: matrices^Cholesky numeric factorization
3107: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3109: Developer Note: fortran interface is not autogenerated as the f90
3110: interface defintion cannot be generated correctly [due to MatFactorInfo]
3112: @*/
3113: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3114: {
3122: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3123: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3124: 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);
3125: MatCheckPreallocated(mat,2);
3127: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3128: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3129: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3130: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3131: PetscObjectStateIncrease((PetscObject)fact);
3132: return(0);
3133: }
3135: /* ----------------------------------------------------------------*/
3138: /*@
3139: MatSolve - Solves A x = b, given a factored matrix.
3141: Neighbor-wise Collective on Mat and Vec
3143: Input Parameters:
3144: + mat - the factored matrix
3145: - b - the right-hand-side vector
3147: Output Parameter:
3148: . x - the result vector
3150: Notes:
3151: The vectors b and x cannot be the same. I.e., one cannot
3152: call MatSolve(A,x,x).
3154: Notes:
3155: Most users should employ the simplified KSP interface for linear solvers
3156: instead of working directly with matrix algebra routines such as this.
3157: See, e.g., KSPCreate().
3159: Level: developer
3161: Concepts: matrices^triangular solves
3163: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3164: @*/
3165: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3166: {
3176: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3177: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3178: 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);
3179: 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);
3180: 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);
3181: if (!mat->rmap->N && !mat->cmap->N) return(0);
3182: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3183: MatCheckPreallocated(mat,1);
3185: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3186: (*mat->ops->solve)(mat,b,x);
3187: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3188: PetscObjectStateIncrease((PetscObject)x);
3189: return(0);
3190: }
3194: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3195: {
3197: Vec b,x;
3198: PetscInt m,N,i;
3199: PetscScalar *bb,*xx;
3200: PetscBool flg;
3203: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3204: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3205: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3206: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3208: MatDenseGetArray(B,&bb);
3209: MatDenseGetArray(X,&xx);
3210: MatGetLocalSize(B,&m,NULL); /* number local rows */
3211: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3212: MatCreateVecs(A,&x,&b);
3213: for (i=0; i<N; i++) {
3214: VecPlaceArray(b,bb + i*m);
3215: VecPlaceArray(x,xx + i*m);
3216: MatSolve(A,b,x);
3217: VecResetArray(x);
3218: VecResetArray(b);
3219: }
3220: VecDestroy(&b);
3221: VecDestroy(&x);
3222: MatDenseRestoreArray(B,&bb);
3223: MatDenseRestoreArray(X,&xx);
3224: return(0);
3225: }
3229: /*@
3230: MatMatSolve - Solves A X = B, given a factored matrix.
3232: Neighbor-wise Collective on Mat
3234: Input Parameters:
3235: + A - the factored matrix
3236: - B - the right-hand-side matrix (dense matrix)
3238: Output Parameter:
3239: . X - the result matrix (dense matrix)
3241: Notes:
3242: The matrices b and x cannot be the same. I.e., one cannot
3243: call MatMatSolve(A,x,x).
3245: Notes:
3246: Most users should usually employ the simplified KSP interface for linear solvers
3247: instead of working directly with matrix algebra routines such as this.
3248: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3249: at a time.
3251: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3252: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3254: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3256: Level: developer
3258: Concepts: matrices^triangular solves
3260: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3261: @*/
3262: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3263: {
3273: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3274: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3275: 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);
3276: 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);
3277: 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);
3278: if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3279: if (!A->rmap->N && !A->cmap->N) return(0);
3280: MatCheckPreallocated(A,1);
3282: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3283: if (!A->ops->matsolve) {
3284: PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3285: MatMatSolve_Basic(A,B,X);
3286: } else {
3287: (*A->ops->matsolve)(A,B,X);
3288: }
3289: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3290: PetscObjectStateIncrease((PetscObject)X);
3291: return(0);
3292: }
3297: /*@
3298: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3299: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3301: Neighbor-wise Collective on Mat and Vec
3303: Input Parameters:
3304: + mat - the factored matrix
3305: - b - the right-hand-side vector
3307: Output Parameter:
3308: . x - the result vector
3310: Notes:
3311: MatSolve() should be used for most applications, as it performs
3312: a forward solve followed by a backward solve.
3314: The vectors b and x cannot be the same, i.e., one cannot
3315: call MatForwardSolve(A,x,x).
3317: For matrix in seqsbaij format with block size larger than 1,
3318: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3319: MatForwardSolve() solves U^T*D y = b, and
3320: MatBackwardSolve() solves U x = y.
3321: Thus they do not provide a symmetric preconditioner.
3323: Most users should employ the simplified KSP interface for linear solvers
3324: instead of working directly with matrix algebra routines such as this.
3325: See, e.g., KSPCreate().
3327: Level: developer
3329: Concepts: matrices^forward solves
3331: .seealso: MatSolve(), MatBackwardSolve()
3332: @*/
3333: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3334: {
3344: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3345: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3346: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3347: 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);
3348: 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);
3349: 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);
3350: MatCheckPreallocated(mat,1);
3351: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3352: (*mat->ops->forwardsolve)(mat,b,x);
3353: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3354: PetscObjectStateIncrease((PetscObject)x);
3355: return(0);
3356: }
3360: /*@
3361: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3362: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3364: Neighbor-wise Collective on Mat and Vec
3366: Input Parameters:
3367: + mat - the factored matrix
3368: - b - the right-hand-side vector
3370: Output Parameter:
3371: . x - the result vector
3373: Notes:
3374: MatSolve() should be used for most applications, as it performs
3375: a forward solve followed by a backward solve.
3377: The vectors b and x cannot be the same. I.e., one cannot
3378: call MatBackwardSolve(A,x,x).
3380: For matrix in seqsbaij format with block size larger than 1,
3381: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3382: MatForwardSolve() solves U^T*D y = b, and
3383: MatBackwardSolve() solves U x = y.
3384: Thus they do not provide a symmetric preconditioner.
3386: Most users should employ the simplified KSP interface for linear solvers
3387: instead of working directly with matrix algebra routines such as this.
3388: See, e.g., KSPCreate().
3390: Level: developer
3392: Concepts: matrices^backward solves
3394: .seealso: MatSolve(), MatForwardSolve()
3395: @*/
3396: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3397: {
3407: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3408: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3409: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3410: 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);
3411: 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);
3412: 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);
3413: MatCheckPreallocated(mat,1);
3415: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3416: (*mat->ops->backwardsolve)(mat,b,x);
3417: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3418: PetscObjectStateIncrease((PetscObject)x);
3419: return(0);
3420: }
3424: /*@
3425: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3427: Neighbor-wise Collective on Mat and Vec
3429: Input Parameters:
3430: + mat - the factored matrix
3431: . b - the right-hand-side vector
3432: - y - the vector to be added to
3434: Output Parameter:
3435: . x - the result vector
3437: Notes:
3438: The vectors b and x cannot be the same. I.e., one cannot
3439: call MatSolveAdd(A,x,y,x).
3441: Most users should employ the simplified KSP interface for linear solvers
3442: instead of working directly with matrix algebra routines such as this.
3443: See, e.g., KSPCreate().
3445: Level: developer
3447: Concepts: matrices^triangular solves
3449: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3450: @*/
3451: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3452: {
3453: PetscScalar one = 1.0;
3454: Vec tmp;
3466: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3467: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3468: 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);
3469: 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);
3470: 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);
3471: 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);
3472: 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);
3473: MatCheckPreallocated(mat,1);
3475: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3476: if (mat->ops->solveadd) {
3477: (*mat->ops->solveadd)(mat,b,y,x);
3478: } else {
3479: /* do the solve then the add manually */
3480: if (x != y) {
3481: MatSolve(mat,b,x);
3482: VecAXPY(x,one,y);
3483: } else {
3484: VecDuplicate(x,&tmp);
3485: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3486: VecCopy(x,tmp);
3487: MatSolve(mat,b,x);
3488: VecAXPY(x,one,tmp);
3489: VecDestroy(&tmp);
3490: }
3491: }
3492: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3493: PetscObjectStateIncrease((PetscObject)x);
3494: return(0);
3495: }
3499: /*@
3500: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3502: Neighbor-wise Collective on Mat and Vec
3504: Input Parameters:
3505: + mat - the factored matrix
3506: - b - the right-hand-side vector
3508: Output Parameter:
3509: . x - the result vector
3511: Notes:
3512: The vectors b and x cannot be the same. I.e., one cannot
3513: call MatSolveTranspose(A,x,x).
3515: Most users should employ the simplified KSP interface for linear solvers
3516: instead of working directly with matrix algebra routines such as this.
3517: See, e.g., KSPCreate().
3519: Level: developer
3521: Concepts: matrices^triangular solves
3523: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3524: @*/
3525: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3526: {
3536: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3537: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3538: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3539: 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);
3540: 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);
3541: MatCheckPreallocated(mat,1);
3542: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3543: (*mat->ops->solvetranspose)(mat,b,x);
3544: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3545: PetscObjectStateIncrease((PetscObject)x);
3546: return(0);
3547: }
3551: /*@
3552: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3553: factored matrix.
3555: Neighbor-wise Collective on Mat and Vec
3557: Input Parameters:
3558: + mat - the factored matrix
3559: . b - the right-hand-side vector
3560: - y - the vector to be added to
3562: Output Parameter:
3563: . x - the result vector
3565: Notes:
3566: The vectors b and x cannot be the same. I.e., one cannot
3567: call MatSolveTransposeAdd(A,x,y,x).
3569: Most users should employ the simplified KSP interface for linear solvers
3570: instead of working directly with matrix algebra routines such as this.
3571: See, e.g., KSPCreate().
3573: Level: developer
3575: Concepts: matrices^triangular solves
3577: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3578: @*/
3579: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3580: {
3581: PetscScalar one = 1.0;
3583: Vec tmp;
3594: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3595: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3596: 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);
3597: 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);
3598: 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);
3599: 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);
3600: MatCheckPreallocated(mat,1);
3602: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3603: if (mat->ops->solvetransposeadd) {
3604: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3605: } else {
3606: /* do the solve then the add manually */
3607: if (x != y) {
3608: MatSolveTranspose(mat,b,x);
3609: VecAXPY(x,one,y);
3610: } else {
3611: VecDuplicate(x,&tmp);
3612: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3613: VecCopy(x,tmp);
3614: MatSolveTranspose(mat,b,x);
3615: VecAXPY(x,one,tmp);
3616: VecDestroy(&tmp);
3617: }
3618: }
3619: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3620: PetscObjectStateIncrease((PetscObject)x);
3621: return(0);
3622: }
3623: /* ----------------------------------------------------------------*/
3627: /*@
3628: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3630: Neighbor-wise Collective on Mat and Vec
3632: Input Parameters:
3633: + mat - the matrix
3634: . b - the right hand side
3635: . omega - the relaxation factor
3636: . flag - flag indicating the type of SOR (see below)
3637: . shift - diagonal shift
3638: . its - the number of iterations
3639: - lits - the number of local iterations
3641: Output Parameters:
3642: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3644: SOR Flags:
3645: . SOR_FORWARD_SWEEP - forward SOR
3646: . SOR_BACKWARD_SWEEP - backward SOR
3647: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3648: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3649: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3650: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3651: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3652: upper/lower triangular part of matrix to
3653: vector (with omega)
3654: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3656: Notes:
3657: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3658: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3659: on each processor.
3661: Application programmers will not generally use MatSOR() directly,
3662: but instead will employ the KSP/PC interface.
3664: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3666: Notes for Advanced Users:
3667: The flags are implemented as bitwise inclusive or operations.
3668: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3669: to specify a zero initial guess for SSOR.
3671: Most users should employ the simplified KSP interface for linear solvers
3672: instead of working directly with matrix algebra routines such as this.
3673: See, e.g., KSPCreate().
3675: Vectors x and b CANNOT be the same
3677: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3679: Level: developer
3681: Concepts: matrices^relaxation
3682: Concepts: matrices^SOR
3683: Concepts: matrices^Gauss-Seidel
3685: @*/
3686: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3687: {
3697: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3698: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3699: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3700: 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);
3701: 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);
3702: 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);
3703: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3704: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3705: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3707: MatCheckPreallocated(mat,1);
3708: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3709: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3710: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3711: PetscObjectStateIncrease((PetscObject)x);
3712: return(0);
3713: }
3717: /*
3718: Default matrix copy routine.
3719: */
3720: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3721: {
3722: PetscErrorCode ierr;
3723: PetscInt i,rstart = 0,rend = 0,nz;
3724: const PetscInt *cwork;
3725: const PetscScalar *vwork;
3728: if (B->assembled) {
3729: MatZeroEntries(B);
3730: }
3731: MatGetOwnershipRange(A,&rstart,&rend);
3732: for (i=rstart; i<rend; i++) {
3733: MatGetRow(A,i,&nz,&cwork,&vwork);
3734: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3735: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3736: }
3737: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3738: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3739: PetscObjectStateIncrease((PetscObject)B);
3740: return(0);
3741: }
3745: /*@
3746: MatCopy - Copys a matrix to another matrix.
3748: Collective on Mat
3750: Input Parameters:
3751: + A - the matrix
3752: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3754: Output Parameter:
3755: . B - where the copy is put
3757: Notes:
3758: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3759: same nonzero pattern or the routine will crash.
3761: MatCopy() copies the matrix entries of a matrix to another existing
3762: matrix (after first zeroing the second matrix). A related routine is
3763: MatConvert(), which first creates a new matrix and then copies the data.
3765: Level: intermediate
3767: Concepts: matrices^copying
3769: .seealso: MatConvert(), MatDuplicate()
3771: @*/
3772: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3773: {
3775: PetscInt i;
3783: MatCheckPreallocated(B,2);
3784: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3785: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3786: 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);
3787: MatCheckPreallocated(A,1);
3789: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3790: if (A->ops->copy) {
3791: (*A->ops->copy)(A,B,str);
3792: } else { /* generic conversion */
3793: MatCopy_Basic(A,B,str);
3794: }
3796: B->stencil.dim = A->stencil.dim;
3797: B->stencil.noc = A->stencil.noc;
3798: for (i=0; i<=A->stencil.dim; i++) {
3799: B->stencil.dims[i] = A->stencil.dims[i];
3800: B->stencil.starts[i] = A->stencil.starts[i];
3801: }
3803: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3804: PetscObjectStateIncrease((PetscObject)B);
3805: return(0);
3806: }
3810: /*@C
3811: MatConvert - Converts a matrix to another matrix, either of the same
3812: or different type.
3814: Collective on Mat
3816: Input Parameters:
3817: + mat - the matrix
3818: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3819: same type as the original matrix.
3820: - reuse - denotes if the destination matrix is to be created or reused. Currently
3821: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3822: MAT_INITIAL_MATRIX.
3824: Output Parameter:
3825: . M - pointer to place new matrix
3827: Notes:
3828: MatConvert() first creates a new matrix and then copies the data from
3829: the first matrix. A related routine is MatCopy(), which copies the matrix
3830: entries of one matrix to another already existing matrix context.
3832: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3833: the MPI communicator of the generated matrix is always the same as the communicator
3834: of the input matrix.
3836: Level: intermediate
3838: Concepts: matrices^converting between storage formats
3840: .seealso: MatCopy(), MatDuplicate()
3841: @*/
3842: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3843: {
3845: PetscBool sametype,issame,flg;
3846: char convname[256],mtype[256];
3847: Mat B;
3853: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3854: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3855: MatCheckPreallocated(mat,1);
3856: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3858: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3859: if (flg) {
3860: newtype = mtype;
3861: }
3862: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3863: PetscStrcmp(newtype,"same",&issame);
3864: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3866: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3868: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3869: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3870: } else {
3871: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3872: const char *prefix[3] = {"seq","mpi",""};
3873: PetscInt i;
3874: /*
3875: Order of precedence:
3876: 1) See if a specialized converter is known to the current matrix.
3877: 2) See if a specialized converter is known to the desired matrix class.
3878: 3) See if a good general converter is registered for the desired class
3879: (as of 6/27/03 only MATMPIADJ falls into this category).
3880: 4) See if a good general converter is known for the current matrix.
3881: 5) Use a really basic converter.
3882: */
3884: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3885: for (i=0; i<3; i++) {
3886: PetscStrcpy(convname,"MatConvert_");
3887: PetscStrcat(convname,((PetscObject)mat)->type_name);
3888: PetscStrcat(convname,"_");
3889: PetscStrcat(convname,prefix[i]);
3890: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3891: PetscStrcat(convname,"_C");
3892: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3893: if (conv) goto foundconv;
3894: }
3896: /* 2) See if a specialized converter is known to the desired matrix class. */
3897: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3898: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3899: MatSetType(B,newtype);
3900: for (i=0; i<3; i++) {
3901: PetscStrcpy(convname,"MatConvert_");
3902: PetscStrcat(convname,((PetscObject)mat)->type_name);
3903: PetscStrcat(convname,"_");
3904: PetscStrcat(convname,prefix[i]);
3905: PetscStrcat(convname,newtype);
3906: PetscStrcat(convname,"_C");
3907: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3908: if (conv) {
3909: MatDestroy(&B);
3910: goto foundconv;
3911: }
3912: }
3914: /* 3) See if a good general converter is registered for the desired class */
3915: conv = B->ops->convertfrom;
3916: MatDestroy(&B);
3917: if (conv) goto foundconv;
3919: /* 4) See if a good general converter is known for the current matrix */
3920: if (mat->ops->convert) {
3921: conv = mat->ops->convert;
3922: }
3923: if (conv) goto foundconv;
3925: /* 5) Use a really basic converter. */
3926: conv = MatConvert_Basic;
3928: foundconv:
3929: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3930: (*conv)(mat,newtype,reuse,M);
3931: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3932: }
3933: PetscObjectStateIncrease((PetscObject)*M);
3935: /* Copy Mat options */
3936: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3937: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3938: return(0);
3939: }
3943: /*@C
3944: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3946: Not Collective
3948: Input Parameter:
3949: . mat - the matrix, must be a factored matrix
3951: Output Parameter:
3952: . type - the string name of the package (do not free this string)
3954: Notes:
3955: In Fortran you pass in a empty string and the package name will be copied into it.
3956: (Make sure the string is long enough)
3958: Level: intermediate
3960: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3961: @*/
3962: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3963: {
3964: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
3969: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3970: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3971: if (!conv) {
3972: *type = MATSOLVERPETSC;
3973: } else {
3974: (*conv)(mat,type);
3975: }
3976: return(0);
3977: }
3979: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
3980: struct _MatSolverPackageForSpecifcType {
3981: MatType mtype;
3982: PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*);
3983: MatSolverPackageForSpecifcType next;
3984: };
3986: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
3987: struct _MatSolverPackageHolder {
3988: char *name;
3989: MatSolverPackageForSpecifcType handlers;
3990: MatSolverPackageHolder next;
3991: };
3993: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
3997: /*@C
3998: MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4000: Input Parameters:
4001: + package - name of the package, for example petsc or superlu
4002: . mtype - the matrix type that works with this package
4003: . ftype - the type of factorization supported by the package
4004: - getfactor - routine that will create the factored matrix ready to be used
4006: Level: intermediate
4008: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4009: @*/
4010: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4011: {
4012: PetscErrorCode ierr;
4013: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4014: PetscBool flg;
4015: MatSolverPackageForSpecifcType inext,iprev = NULL;
4018: if (!MatSolverPackageHolders) {
4019: PetscNew(&MatSolverPackageHolders);
4020: PetscStrallocpy(package,&MatSolverPackageHolders->name);
4021: PetscNew(&MatSolverPackageHolders->handlers);
4022: PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4023: MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4024: return(0);
4025: }
4026: while (next) {
4027: PetscStrcasecmp(package,next->name,&flg);
4028: if (flg) {
4029: inext = next->handlers;
4030: while (inext) {
4031: PetscStrcasecmp(mtype,inext->mtype,&flg);
4032: if (flg) {
4033: inext->getfactor[(int)ftype-1] = getfactor;
4034: return(0);
4035: }
4036: iprev = inext;
4037: inext = inext->next;
4038: }
4039: PetscNew(&iprev->next);
4040: PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4041: iprev->next->getfactor[(int)ftype-1] = getfactor;
4042: return(0);
4043: }
4044: prev = next;
4045: next = next->next;
4046: }
4047: PetscNew(&prev->next);
4048: PetscStrallocpy(package,&prev->next->name);
4049: PetscNew(&prev->next->handlers);
4050: PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4051: prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4052: return(0);
4053: }
4057: /*@C
4058: MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4060: Input Parameters:
4061: + package - name of the package, for example petsc or superlu
4062: . ftype - the type of factorization supported by the package
4063: - mtype - the matrix type that works with this package
4065: Output Parameters:
4066: + foundpackage - PETSC_TRUE if the package was registered
4067: . foundmtype - PETSC_TRUE if the package supports the requested mtype
4068: - getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4070: Level: intermediate
4072: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4073: @*/
4074: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4075: {
4076: PetscErrorCode ierr;
4077: MatSolverPackageHolder next = MatSolverPackageHolders;
4078: PetscBool flg;
4079: MatSolverPackageForSpecifcType inext;
4082: if (foundpackage) *foundpackage = PETSC_FALSE;
4083: if (foundmtype) *foundmtype = PETSC_FALSE;
4084: if (getfactor) *getfactor = NULL;
4085: while (next) {
4086: PetscStrcasecmp(package,next->name,&flg);
4087: if (flg) {
4088: if (foundpackage) *foundpackage = PETSC_TRUE;
4089: inext = next->handlers;
4090: while (inext) {
4091: PetscStrcasecmp(mtype,inext->mtype,&flg);
4092: if (flg) {
4093: if (foundmtype) *foundmtype = PETSC_TRUE;
4094: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4095: return(0);
4096: }
4097: inext = inext->next;
4098: }
4099: }
4100: next = next->next;
4101: }
4102: return(0);
4103: }
4107: PetscErrorCode MatSolverPackageDestroy(void)
4108: {
4109: PetscErrorCode ierr;
4110: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4111: MatSolverPackageForSpecifcType inext,iprev;
4114: while (next) {
4115: PetscFree(next->name);
4116: inext = next->handlers;
4117: while (inext) {
4118: PetscFree(inext->mtype);
4119: iprev = inext;
4120: inext = inext->next;
4121: PetscFree(iprev);
4122: }
4123: prev = next;
4124: next = next->next;
4125: PetscFree(prev);
4126: }
4127: MatSolverPackageHolders = NULL;
4128: return(0);
4129: }
4133: /*@C
4134: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4136: Collective on Mat
4138: Input Parameters:
4139: + mat - the matrix
4140: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4141: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4143: Output Parameters:
4144: . f - the factor matrix used with MatXXFactorSymbolic() calls
4146: Notes:
4147: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4148: such as pastix, superlu, mumps etc.
4150: PETSc must have been ./configure to use the external solver, using the option --download-package
4152: Level: intermediate
4154: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4155: @*/
4156: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4157: {
4158: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4159: PetscBool foundpackage,foundmtype;
4165: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4166: MatCheckPreallocated(mat,1);
4168: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4169: if (!foundpackage) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4170: if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4171: if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4173: (*conv)(mat,ftype,f);
4174: return(0);
4175: }
4179: /*@C
4180: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4182: Not Collective
4184: Input Parameters:
4185: + mat - the matrix
4186: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4187: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4189: Output Parameter:
4190: . flg - PETSC_TRUE if the factorization is available
4192: Notes:
4193: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4194: such as pastix, superlu, mumps etc.
4196: PETSc must have been ./configure to use the external solver, using the option --download-package
4198: Level: intermediate
4200: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4201: @*/
4202: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
4203: {
4204: PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4210: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4211: MatCheckPreallocated(mat,1);
4213: *flg = PETSC_FALSE;
4214: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4215: if (gconv) {
4216: *flg = PETSC_TRUE;
4217: }
4218: return(0);
4219: }
4221: #include <petscdmtypes.h>
4225: /*@
4226: MatDuplicate - Duplicates a matrix including the non-zero structure.
4228: Collective on Mat
4230: Input Parameters:
4231: + mat - the matrix
4232: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4233: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4235: Output Parameter:
4236: . M - pointer to place new matrix
4238: Level: intermediate
4240: Concepts: matrices^duplicating
4242: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4244: .seealso: MatCopy(), MatConvert()
4245: @*/
4246: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4247: {
4249: Mat B;
4250: PetscInt i;
4251: DM dm;
4257: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4258: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4259: MatCheckPreallocated(mat,1);
4261: *M = 0;
4262: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4263: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4264: (*mat->ops->duplicate)(mat,op,M);
4265: B = *M;
4267: B->stencil.dim = mat->stencil.dim;
4268: B->stencil.noc = mat->stencil.noc;
4269: for (i=0; i<=mat->stencil.dim; i++) {
4270: B->stencil.dims[i] = mat->stencil.dims[i];
4271: B->stencil.starts[i] = mat->stencil.starts[i];
4272: }
4274: B->nooffproczerorows = mat->nooffproczerorows;
4275: B->nooffprocentries = mat->nooffprocentries;
4277: PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4278: if (dm) {
4279: PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4280: }
4281: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4282: PetscObjectStateIncrease((PetscObject)B);
4283: return(0);
4284: }
4288: /*@
4289: MatGetDiagonal - Gets the diagonal of a matrix.
4291: Logically Collective on Mat and Vec
4293: Input Parameters:
4294: + mat - the matrix
4295: - v - the vector for storing the diagonal
4297: Output Parameter:
4298: . v - the diagonal of the matrix
4300: Level: intermediate
4302: Note:
4303: Currently only correct in parallel for square matrices.
4305: Concepts: matrices^accessing diagonals
4307: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4308: @*/
4309: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4310: {
4317: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4318: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4319: MatCheckPreallocated(mat,1);
4321: (*mat->ops->getdiagonal)(mat,v);
4322: PetscObjectStateIncrease((PetscObject)v);
4323: return(0);
4324: }
4328: /*@C
4329: MatGetRowMin - Gets the minimum value (of the real part) of each
4330: row of the matrix
4332: Logically Collective on Mat and Vec
4334: Input Parameters:
4335: . mat - the matrix
4337: Output Parameter:
4338: + v - the vector for storing the maximums
4339: - idx - the indices of the column found for each row (optional)
4341: Level: intermediate
4343: Notes: The result of this call are the same as if one converted the matrix to dense format
4344: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4346: This code is only implemented for a couple of matrix formats.
4348: Concepts: matrices^getting row maximums
4350: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4351: MatGetRowMax()
4352: @*/
4353: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4354: {
4361: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4362: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4363: MatCheckPreallocated(mat,1);
4365: (*mat->ops->getrowmin)(mat,v,idx);
4366: PetscObjectStateIncrease((PetscObject)v);
4367: return(0);
4368: }
4372: /*@C
4373: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4374: row of the matrix
4376: Logically Collective on Mat and Vec
4378: Input Parameters:
4379: . mat - the matrix
4381: Output Parameter:
4382: + v - the vector for storing the minimums
4383: - idx - the indices of the column found for each row (or NULL if not needed)
4385: Level: intermediate
4387: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4388: row is 0 (the first column).
4390: This code is only implemented for a couple of matrix formats.
4392: Concepts: matrices^getting row maximums
4394: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4395: @*/
4396: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4397: {
4404: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4405: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4406: MatCheckPreallocated(mat,1);
4407: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4409: (*mat->ops->getrowminabs)(mat,v,idx);
4410: PetscObjectStateIncrease((PetscObject)v);
4411: return(0);
4412: }
4416: /*@C
4417: MatGetRowMax - Gets the maximum value (of the real part) of each
4418: row of the matrix
4420: Logically Collective on Mat and Vec
4422: Input Parameters:
4423: . mat - the matrix
4425: Output Parameter:
4426: + v - the vector for storing the maximums
4427: - idx - the indices of the column found for each row (optional)
4429: Level: intermediate
4431: Notes: The result of this call are the same as if one converted the matrix to dense format
4432: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4434: This code is only implemented for a couple of matrix formats.
4436: Concepts: matrices^getting row maximums
4438: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4439: @*/
4440: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4441: {
4448: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4449: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4450: MatCheckPreallocated(mat,1);
4452: (*mat->ops->getrowmax)(mat,v,idx);
4453: PetscObjectStateIncrease((PetscObject)v);
4454: return(0);
4455: }
4459: /*@C
4460: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4461: row of the matrix
4463: Logically Collective on Mat and Vec
4465: Input Parameters:
4466: . mat - the matrix
4468: Output Parameter:
4469: + v - the vector for storing the maximums
4470: - idx - the indices of the column found for each row (or NULL if not needed)
4472: Level: intermediate
4474: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4475: row is 0 (the first column).
4477: This code is only implemented for a couple of matrix formats.
4479: Concepts: matrices^getting row maximums
4481: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4482: @*/
4483: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4484: {
4491: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4492: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4493: MatCheckPreallocated(mat,1);
4494: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4496: (*mat->ops->getrowmaxabs)(mat,v,idx);
4497: PetscObjectStateIncrease((PetscObject)v);
4498: return(0);
4499: }
4503: /*@
4504: MatGetRowSum - Gets the sum of each row of the matrix
4506: Logically Collective on Mat and Vec
4508: Input Parameters:
4509: . mat - the matrix
4511: Output Parameter:
4512: . v - the vector for storing the sum of rows
4514: Level: intermediate
4516: Notes: This code is slow since it is not currently specialized for different formats
4518: Concepts: matrices^getting row sums
4520: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4521: @*/
4522: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4523: {
4524: PetscInt start = 0, end = 0, row;
4525: PetscScalar *array;
4532: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4533: MatCheckPreallocated(mat,1);
4534: MatGetOwnershipRange(mat, &start, &end);
4535: VecGetArray(v, &array);
4536: for (row = start; row < end; ++row) {
4537: PetscInt ncols, col;
4538: const PetscInt *cols;
4539: const PetscScalar *vals;
4541: array[row - start] = 0.0;
4543: MatGetRow(mat, row, &ncols, &cols, &vals);
4544: for (col = 0; col < ncols; col++) {
4545: array[row - start] += vals[col];
4546: }
4547: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4548: }
4549: VecRestoreArray(v, &array);
4550: PetscObjectStateIncrease((PetscObject) v);
4551: return(0);
4552: }
4556: /*@
4557: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4559: Collective on Mat
4561: Input Parameter:
4562: + mat - the matrix to transpose
4563: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4565: Output Parameters:
4566: . B - the transpose
4568: Notes:
4569: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4571: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4573: Level: intermediate
4575: Concepts: matrices^transposing
4577: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4578: @*/
4579: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4580: {
4586: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4587: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4588: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4589: MatCheckPreallocated(mat,1);
4591: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4592: (*mat->ops->transpose)(mat,reuse,B);
4593: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4594: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4595: return(0);
4596: }
4600: /*@
4601: MatIsTranspose - Test whether a matrix is another one's transpose,
4602: or its own, in which case it tests symmetry.
4604: Collective on Mat
4606: Input Parameter:
4607: + A - the matrix to test
4608: - B - the matrix to test against, this can equal the first parameter
4610: Output Parameters:
4611: . flg - the result
4613: Notes:
4614: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4615: has a running time of the order of the number of nonzeros; the parallel
4616: test involves parallel copies of the block-offdiagonal parts of the matrix.
4618: Level: intermediate
4620: Concepts: matrices^transposing, matrix^symmetry
4622: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4623: @*/
4624: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4625: {
4626: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4632: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4633: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4634: *flg = PETSC_FALSE;
4635: if (f && g) {
4636: if (f == g) {
4637: (*f)(A,B,tol,flg);
4638: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4639: } else {
4640: MatType mattype;
4641: if (!f) {
4642: MatGetType(A,&mattype);
4643: } else {
4644: MatGetType(B,&mattype);
4645: }
4646: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4647: }
4648: return(0);
4649: }
4653: /*@
4654: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4656: Collective on Mat
4658: Input Parameter:
4659: + mat - the matrix to transpose and complex conjugate
4660: - reuse - store the transpose matrix in the provided B
4662: Output Parameters:
4663: . B - the Hermitian
4665: Notes:
4666: If you pass in &mat for B the Hermitian will be done in place
4668: Level: intermediate
4670: Concepts: matrices^transposing, complex conjugatex
4672: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4673: @*/
4674: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4675: {
4679: MatTranspose(mat,reuse,B);
4680: #if defined(PETSC_USE_COMPLEX)
4681: MatConjugate(*B);
4682: #endif
4683: return(0);
4684: }
4688: /*@
4689: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4691: Collective on Mat
4693: Input Parameter:
4694: + A - the matrix to test
4695: - B - the matrix to test against, this can equal the first parameter
4697: Output Parameters:
4698: . flg - the result
4700: Notes:
4701: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4702: has a running time of the order of the number of nonzeros; the parallel
4703: test involves parallel copies of the block-offdiagonal parts of the matrix.
4705: Level: intermediate
4707: Concepts: matrices^transposing, matrix^symmetry
4709: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4710: @*/
4711: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4712: {
4713: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4719: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4720: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4721: if (f && g) {
4722: if (f==g) {
4723: (*f)(A,B,tol,flg);
4724: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4725: }
4726: return(0);
4727: }
4731: /*@
4732: MatPermute - Creates a new matrix with rows and columns permuted from the
4733: original.
4735: Collective on Mat
4737: Input Parameters:
4738: + mat - the matrix to permute
4739: . row - row permutation, each processor supplies only the permutation for its rows
4740: - col - column permutation, each processor supplies only the permutation for its columns
4742: Output Parameters:
4743: . B - the permuted matrix
4745: Level: advanced
4747: Note:
4748: The index sets map from row/col of permuted matrix to row/col of original matrix.
4749: The index sets should be on the same communicator as Mat and have the same local sizes.
4751: Concepts: matrices^permuting
4753: .seealso: MatGetOrdering(), ISAllGather()
4755: @*/
4756: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4757: {
4766: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4767: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4768: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4769: MatCheckPreallocated(mat,1);
4771: (*mat->ops->permute)(mat,row,col,B);
4772: PetscObjectStateIncrease((PetscObject)*B);
4773: return(0);
4774: }
4778: /*@
4779: MatEqual - Compares two matrices.
4781: Collective on Mat
4783: Input Parameters:
4784: + A - the first matrix
4785: - B - the second matrix
4787: Output Parameter:
4788: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4790: Level: intermediate
4792: Concepts: matrices^equality between
4793: @*/
4794: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4795: {
4805: MatCheckPreallocated(B,2);
4806: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4807: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4808: 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);
4809: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4810: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4811: 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);
4812: MatCheckPreallocated(A,1);
4814: (*A->ops->equal)(A,B,flg);
4815: return(0);
4816: }
4820: /*@
4821: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4822: matrices that are stored as vectors. Either of the two scaling
4823: matrices can be NULL.
4825: Collective on Mat
4827: Input Parameters:
4828: + mat - the matrix to be scaled
4829: . l - the left scaling vector (or NULL)
4830: - r - the right scaling vector (or NULL)
4832: Notes:
4833: MatDiagonalScale() computes A = LAR, where
4834: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4835: The L scales the rows of the matrix, the R scales the columns of the matrix.
4837: Level: intermediate
4839: Concepts: matrices^diagonal scaling
4840: Concepts: diagonal scaling of matrices
4842: .seealso: MatScale()
4843: @*/
4844: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4845: {
4851: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4854: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4855: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4856: MatCheckPreallocated(mat,1);
4858: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4859: (*mat->ops->diagonalscale)(mat,l,r);
4860: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4861: PetscObjectStateIncrease((PetscObject)mat);
4862: #if defined(PETSC_HAVE_CUSP)
4863: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4864: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4865: }
4866: #endif
4867: #if defined(PETSC_HAVE_VIENNACL)
4868: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4869: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4870: }
4871: #endif
4872: return(0);
4873: }
4877: /*@
4878: MatScale - Scales all elements of a matrix by a given number.
4880: Logically Collective on Mat
4882: Input Parameters:
4883: + mat - the matrix to be scaled
4884: - a - the scaling value
4886: Output Parameter:
4887: . mat - the scaled matrix
4889: Level: intermediate
4891: Concepts: matrices^scaling all entries
4893: .seealso: MatDiagonalScale()
4894: @*/
4895: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4896: {
4902: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4903: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4904: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4906: MatCheckPreallocated(mat,1);
4908: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4909: if (a != (PetscScalar)1.0) {
4910: (*mat->ops->scale)(mat,a);
4911: PetscObjectStateIncrease((PetscObject)mat);
4912: }
4913: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4914: #if defined(PETSC_HAVE_CUSP)
4915: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4916: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4917: }
4918: #endif
4919: #if defined(PETSC_HAVE_VIENNACL)
4920: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4921: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4922: }
4923: #endif
4924: return(0);
4925: }
4929: /*@
4930: MatNorm - Calculates various norms of a matrix.
4932: Collective on Mat
4934: Input Parameters:
4935: + mat - the matrix
4936: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4938: Output Parameters:
4939: . nrm - the resulting norm
4941: Level: intermediate
4943: Concepts: matrices^norm
4944: Concepts: norm^of matrix
4945: @*/
4946: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4947: {
4955: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4956: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4957: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4958: MatCheckPreallocated(mat,1);
4960: (*mat->ops->norm)(mat,type,nrm);
4961: return(0);
4962: }
4964: /*
4965: This variable is used to prevent counting of MatAssemblyBegin() that
4966: are called from within a MatAssemblyEnd().
4967: */
4968: static PetscInt MatAssemblyEnd_InUse = 0;
4971: /*@
4972: MatAssemblyBegin - Begins assembling the matrix. This routine should
4973: be called after completing all calls to MatSetValues().
4975: Collective on Mat
4977: Input Parameters:
4978: + mat - the matrix
4979: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4981: Notes:
4982: MatSetValues() generally caches the values. The matrix is ready to
4983: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4984: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4985: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4986: using the matrix.
4988: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4989: 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
4990: a global collective operation requring all processes that share the matrix.
4992: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4993: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4994: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4996: Level: beginner
4998: Concepts: matrices^assembling
5000: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5001: @*/
5002: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5003: {
5009: MatCheckPreallocated(mat,1);
5010: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5011: if (mat->assembled) {
5012: mat->was_assembled = PETSC_TRUE;
5013: mat->assembled = PETSC_FALSE;
5014: }
5015: if (!MatAssemblyEnd_InUse) {
5016: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5017: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5018: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5019: } else if (mat->ops->assemblybegin) {
5020: (*mat->ops->assemblybegin)(mat,type);
5021: }
5022: return(0);
5023: }
5027: /*@
5028: MatAssembled - Indicates if a matrix has been assembled and is ready for
5029: use; for example, in matrix-vector product.
5031: Not Collective
5033: Input Parameter:
5034: . mat - the matrix
5036: Output Parameter:
5037: . assembled - PETSC_TRUE or PETSC_FALSE
5039: Level: advanced
5041: Concepts: matrices^assembled?
5043: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5044: @*/
5045: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5046: {
5051: *assembled = mat->assembled;
5052: return(0);
5053: }
5057: /*@
5058: MatAssemblyEnd - Completes assembling the matrix. This routine should
5059: be called after MatAssemblyBegin().
5061: Collective on Mat
5063: Input Parameters:
5064: + mat - the matrix
5065: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5067: Options Database Keys:
5068: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5069: . -mat_view ::ascii_info_detail - Prints more detailed info
5070: . -mat_view - Prints matrix in ASCII format
5071: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5072: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5073: . -display <name> - Sets display name (default is host)
5074: . -draw_pause <sec> - Sets number of seconds to pause after display
5075: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5076: . -viewer_socket_machine <machine> - Machine to use for socket
5077: . -viewer_socket_port <port> - Port number to use for socket
5078: - -mat_view binary:filename[:append] - Save matrix to file in binary format
5080: Notes:
5081: MatSetValues() generally caches the values. The matrix is ready to
5082: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5083: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5084: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5085: using the matrix.
5087: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5088: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5089: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5091: Level: beginner
5093: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5094: @*/
5095: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5096: {
5097: PetscErrorCode ierr;
5098: static PetscInt inassm = 0;
5099: PetscBool flg = PETSC_FALSE;
5105: inassm++;
5106: MatAssemblyEnd_InUse++;
5107: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5108: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5109: if (mat->ops->assemblyend) {
5110: (*mat->ops->assemblyend)(mat,type);
5111: }
5112: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5113: } else if (mat->ops->assemblyend) {
5114: (*mat->ops->assemblyend)(mat,type);
5115: }
5117: /* Flush assembly is not a true assembly */
5118: if (type != MAT_FLUSH_ASSEMBLY) {
5119: mat->assembled = PETSC_TRUE; mat->num_ass++;
5120: }
5121: mat->insertmode = NOT_SET_VALUES;
5122: MatAssemblyEnd_InUse--;
5123: PetscObjectStateIncrease((PetscObject)mat);
5124: if (!mat->symmetric_eternal) {
5125: mat->symmetric_set = PETSC_FALSE;
5126: mat->hermitian_set = PETSC_FALSE;
5127: mat->structurally_symmetric_set = PETSC_FALSE;
5128: }
5129: #if defined(PETSC_HAVE_CUSP)
5130: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5131: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5132: }
5133: #endif
5134: #if defined(PETSC_HAVE_VIENNACL)
5135: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5136: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5137: }
5138: #endif
5139: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5140: MatViewFromOptions(mat,NULL,"-mat_view");
5142: if (mat->checksymmetryonassembly) {
5143: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5144: if (flg) {
5145: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5146: } else {
5147: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5148: }
5149: }
5150: if (mat->nullsp && mat->checknullspaceonassembly) {
5151: MatNullSpaceTest(mat->nullsp,mat,NULL);
5152: }
5153: }
5154: inassm--;
5155: return(0);
5156: }
5160: /*@
5161: MatSetOption - Sets a parameter option for a matrix. Some options
5162: may be specific to certain storage formats. Some options
5163: determine how values will be inserted (or added). Sorted,
5164: row-oriented input will generally assemble the fastest. The default
5165: is row-oriented.
5167: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5169: Input Parameters:
5170: + mat - the matrix
5171: . option - the option, one of those listed below (and possibly others),
5172: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5174: Options Describing Matrix Structure:
5175: + MAT_SPD - symmetric positive definite
5176: . MAT_SYMMETRIC - symmetric in terms of both structure and value
5177: . MAT_HERMITIAN - transpose is the complex conjugation
5178: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5179: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5180: you set to be kept with all future use of the matrix
5181: including after MatAssemblyBegin/End() which could
5182: potentially change the symmetry structure, i.e. you
5183: KNOW the matrix will ALWAYS have the property you set.
5186: Options For Use with MatSetValues():
5187: Insert a logically dense subblock, which can be
5188: . MAT_ROW_ORIENTED - row-oriented (default)
5190: Note these options reflect the data you pass in with MatSetValues(); it has
5191: nothing to do with how the data is stored internally in the matrix
5192: data structure.
5194: When (re)assembling a matrix, we can restrict the input for
5195: efficiency/debugging purposes. These options include:
5196: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5197: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5198: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5199: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5200: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5201: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5202: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5203: performance for very large process counts.
5205: Notes:
5206: Some options are relevant only for particular matrix types and
5207: are thus ignored by others. Other options are not supported by
5208: certain matrix types and will generate an error message if set.
5210: If using a Fortran 77 module to compute a matrix, one may need to
5211: use the column-oriented option (or convert to the row-oriented
5212: format).
5214: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5215: that would generate a new entry in the nonzero structure is instead
5216: ignored. Thus, if memory has not alredy been allocated for this particular
5217: data, then the insertion is ignored. For dense matrices, in which
5218: the entire array is allocated, no entries are ever ignored.
5219: Set after the first MatAssemblyEnd()
5221: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5222: that would generate a new entry in the nonzero structure instead produces
5223: an error. (Currently supported for AIJ and BAIJ formats only.)
5225: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5226: that would generate a new entry that has not been preallocated will
5227: instead produce an error. (Currently supported for AIJ and BAIJ formats
5228: only.) This is a useful flag when debugging matrix memory preallocation.
5230: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5231: other processors should be dropped, rather than stashed.
5232: This is useful if you know that the "owning" processor is also
5233: always generating the correct matrix entries, so that PETSc need
5234: not transfer duplicate entries generated on another processor.
5236: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5237: searches during matrix assembly. When this flag is set, the hash table
5238: is created during the first Matrix Assembly. This hash table is
5239: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5240: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5241: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5242: supported by MATMPIBAIJ format only.
5244: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5245: are kept in the nonzero structure
5247: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5248: a zero location in the matrix
5250: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5251: ROWBS matrix types
5253: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5254: zero row routines and thus improves performance for very large process counts.
5256: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5257: part of the matrix (since they should match the upper triangular part).
5259: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5261: Level: intermediate
5263: Concepts: matrices^setting options
5265: .seealso: MatOption, Mat
5267: @*/
5268: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5269: {
5275: if (op > 0) {
5278: }
5280: 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);
5281: 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()");
5283: switch (op) {
5284: case MAT_NO_OFF_PROC_ENTRIES:
5285: mat->nooffprocentries = flg;
5286: return(0);
5287: break;
5288: case MAT_NO_OFF_PROC_ZERO_ROWS:
5289: mat->nooffproczerorows = flg;
5290: return(0);
5291: break;
5292: case MAT_SPD:
5293: mat->spd_set = PETSC_TRUE;
5294: mat->spd = flg;
5295: if (flg) {
5296: mat->symmetric = PETSC_TRUE;
5297: mat->structurally_symmetric = PETSC_TRUE;
5298: mat->symmetric_set = PETSC_TRUE;
5299: mat->structurally_symmetric_set = PETSC_TRUE;
5300: }
5301: break;
5302: case MAT_SYMMETRIC:
5303: mat->symmetric = flg;
5304: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5305: mat->symmetric_set = PETSC_TRUE;
5306: mat->structurally_symmetric_set = flg;
5307: break;
5308: case MAT_HERMITIAN:
5309: mat->hermitian = flg;
5310: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5311: mat->hermitian_set = PETSC_TRUE;
5312: mat->structurally_symmetric_set = flg;
5313: break;
5314: case MAT_STRUCTURALLY_SYMMETRIC:
5315: mat->structurally_symmetric = flg;
5316: mat->structurally_symmetric_set = PETSC_TRUE;
5317: break;
5318: case MAT_SYMMETRY_ETERNAL:
5319: mat->symmetric_eternal = flg;
5320: break;
5321: default:
5322: break;
5323: }
5324: if (mat->ops->setoption) {
5325: (*mat->ops->setoption)(mat,op,flg);
5326: }
5327: return(0);
5328: }
5332: /*@
5333: MatGetOption - Gets a parameter option that has been set for a matrix.
5335: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5337: Input Parameters:
5338: + mat - the matrix
5339: - option - the option, this only responds to certain options, check the code for which ones
5341: Output Parameter:
5342: . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5344: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5346: Level: intermediate
5348: Concepts: matrices^setting options
5350: .seealso: MatOption, MatSetOption()
5352: @*/
5353: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5354: {
5359: 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);
5360: if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5362: switch (op) {
5363: case MAT_NO_OFF_PROC_ENTRIES:
5364: *flg = mat->nooffprocentries;
5365: break;
5366: case MAT_NO_OFF_PROC_ZERO_ROWS:
5367: *flg = mat->nooffproczerorows;
5368: break;
5369: case MAT_SYMMETRIC:
5370: *flg = mat->symmetric;
5371: break;
5372: case MAT_HERMITIAN:
5373: *flg = mat->hermitian;
5374: break;
5375: case MAT_STRUCTURALLY_SYMMETRIC:
5376: *flg = mat->structurally_symmetric;
5377: break;
5378: case MAT_SYMMETRY_ETERNAL:
5379: *flg = mat->symmetric_eternal;
5380: break;
5381: default:
5382: break;
5383: }
5384: return(0);
5385: }
5389: /*@
5390: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5391: this routine retains the old nonzero structure.
5393: Logically Collective on Mat
5395: Input Parameters:
5396: . mat - the matrix
5398: Level: intermediate
5400: 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.
5401: See the Performance chapter of the users manual for information on preallocating matrices.
5403: Concepts: matrices^zeroing
5405: .seealso: MatZeroRows()
5406: @*/
5407: PetscErrorCode MatZeroEntries(Mat mat)
5408: {
5414: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5415: 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");
5416: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5417: MatCheckPreallocated(mat,1);
5419: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5420: (*mat->ops->zeroentries)(mat);
5421: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5422: PetscObjectStateIncrease((PetscObject)mat);
5423: #if defined(PETSC_HAVE_CUSP)
5424: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5425: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5426: }
5427: #endif
5428: #if defined(PETSC_HAVE_VIENNACL)
5429: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5430: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5431: }
5432: #endif
5433: return(0);
5434: }
5438: /*@C
5439: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5440: of a set of rows and columns of a matrix.
5442: Collective on Mat
5444: Input Parameters:
5445: + mat - the matrix
5446: . numRows - the number of rows to remove
5447: . rows - the global row indices
5448: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5449: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5450: - b - optional vector of right hand side, that will be adjusted by provided solution
5452: Notes:
5453: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
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 option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5469: Level: intermediate
5471: Concepts: matrices^zeroing rows
5473: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5474: @*/
5475: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5476: {
5483: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5484: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5485: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5486: MatCheckPreallocated(mat,1);
5488: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5489: MatViewFromOptions(mat,NULL,"-mat_view");
5490: PetscObjectStateIncrease((PetscObject)mat);
5491: #if defined(PETSC_HAVE_CUSP)
5492: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5493: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5494: }
5495: #endif
5496: #if defined(PETSC_HAVE_VIENNACL)
5497: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5498: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5499: }
5500: #endif
5501: return(0);
5502: }
5506: /*@C
5507: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5508: of a set of rows and columns of a matrix.
5510: Collective on Mat
5512: Input Parameters:
5513: + mat - the matrix
5514: . is - the rows to zero
5515: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5516: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5517: - b - optional vector of right hand side, that will be adjusted by provided solution
5519: Notes:
5520: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5522: The user can set a value in the diagonal entry (or for the AIJ and
5523: row formats can optionally remove the main diagonal entry from the
5524: nonzero structure as well, by passing 0.0 as the final argument).
5526: For the parallel case, all processes that share the matrix (i.e.,
5527: those in the communicator used for matrix creation) MUST call this
5528: routine, regardless of whether any rows being zeroed are owned by
5529: them.
5531: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5532: list only rows local to itself).
5534: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5536: Level: intermediate
5538: Concepts: matrices^zeroing rows
5540: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5541: @*/
5542: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5543: {
5545: PetscInt numRows;
5546: const PetscInt *rows;
5553: ISGetLocalSize(is,&numRows);
5554: ISGetIndices(is,&rows);
5555: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5556: ISRestoreIndices(is,&rows);
5557: return(0);
5558: }
5562: /*@C
5563: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5564: of a set of rows of a matrix.
5566: Collective on Mat
5568: Input Parameters:
5569: + mat - the matrix
5570: . numRows - the number of rows to remove
5571: . rows - the global row indices
5572: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5573: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5574: - b - optional vector of right hand side, that will be adjusted by provided solution
5576: Notes:
5577: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5578: but does not release memory. For the dense and block diagonal
5579: formats this does not alter the nonzero structure.
5581: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5582: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5583: merely zeroed.
5585: The user can set a value in the diagonal entry (or for the AIJ and
5586: row formats can optionally remove the main diagonal entry from the
5587: nonzero structure as well, by passing 0.0 as the final argument).
5589: For the parallel case, all processes that share the matrix (i.e.,
5590: those in the communicator used for matrix creation) MUST call this
5591: routine, regardless of whether any rows being zeroed are owned by
5592: them.
5594: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5595: list only rows local to itself).
5597: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5598: owns that are to be zeroed. This saves a global synchronization in the implementation.
5600: Level: intermediate
5602: Concepts: matrices^zeroing rows
5604: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5605: @*/
5606: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5607: {
5614: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5615: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5616: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5617: MatCheckPreallocated(mat,1);
5619: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5620: MatViewFromOptions(mat,NULL,"-mat_view");
5621: PetscObjectStateIncrease((PetscObject)mat);
5622: #if defined(PETSC_HAVE_CUSP)
5623: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5624: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5625: }
5626: #endif
5627: #if defined(PETSC_HAVE_VIENNACL)
5628: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5629: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5630: }
5631: #endif
5632: return(0);
5633: }
5637: /*@C
5638: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5639: of a set of rows of a matrix.
5641: Collective on Mat
5643: Input Parameters:
5644: + mat - the matrix
5645: . is - index set of rows to remove
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: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5652: but does not release memory. For the dense and block diagonal
5653: formats this does not alter the nonzero structure.
5655: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5656: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5657: merely zeroed.
5659: The user can set a value in the diagonal entry (or for the AIJ and
5660: row formats can optionally remove the main diagonal entry from the
5661: nonzero structure as well, by passing 0.0 as the final argument).
5663: For the parallel case, all processes that share the matrix (i.e.,
5664: those in the communicator used for matrix creation) MUST call this
5665: routine, regardless of whether any rows being zeroed are owned by
5666: them.
5668: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5669: list only rows local to itself).
5671: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5672: owns that are to be zeroed. This saves a global synchronization in the implementation.
5674: Level: intermediate
5676: Concepts: matrices^zeroing rows
5678: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5679: @*/
5680: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5681: {
5682: PetscInt numRows;
5683: const PetscInt *rows;
5690: ISGetLocalSize(is,&numRows);
5691: ISGetIndices(is,&rows);
5692: MatZeroRows(mat,numRows,rows,diag,x,b);
5693: ISRestoreIndices(is,&rows);
5694: return(0);
5695: }
5699: /*@C
5700: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5701: of a set of rows of a matrix. These rows must be local to the process.
5703: Collective on Mat
5705: Input Parameters:
5706: + mat - the matrix
5707: . numRows - the number of rows to remove
5708: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5709: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5710: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5711: - b - optional vector of right hand side, that will be adjusted by provided solution
5713: Notes:
5714: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5715: but does not release memory. For the dense and block diagonal
5716: formats this does not alter the nonzero structure.
5718: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5719: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5720: merely zeroed.
5722: The user can set a value in the diagonal entry (or for the AIJ and
5723: row formats can optionally remove the main diagonal entry from the
5724: nonzero structure as well, by passing 0.0 as the final argument).
5726: For the parallel case, all processes that share the matrix (i.e.,
5727: those in the communicator used for matrix creation) MUST call this
5728: routine, regardless of whether any rows being zeroed are owned by
5729: them.
5731: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5732: list only rows local to itself).
5734: The grid coordinates are across the entire grid, not just the local portion
5736: In Fortran idxm and idxn should be declared as
5737: $ MatStencil idxm(4,m)
5738: and the values inserted using
5739: $ idxm(MatStencil_i,1) = i
5740: $ idxm(MatStencil_j,1) = j
5741: $ idxm(MatStencil_k,1) = k
5742: $ idxm(MatStencil_c,1) = c
5743: etc
5745: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5746: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5747: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5748: DM_BOUNDARY_PERIODIC boundary type.
5750: 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
5751: a single value per point) you can skip filling those indices.
5753: Level: intermediate
5755: Concepts: matrices^zeroing rows
5757: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5758: @*/
5759: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5760: {
5761: PetscInt dim = mat->stencil.dim;
5762: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5763: PetscInt *dims = mat->stencil.dims+1;
5764: PetscInt *starts = mat->stencil.starts;
5765: PetscInt *dxm = (PetscInt*) rows;
5766: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5774: PetscMalloc1(numRows, &jdxm);
5775: for (i = 0; i < numRows; ++i) {
5776: /* Skip unused dimensions (they are ordered k, j, i, c) */
5777: for (j = 0; j < 3-sdim; ++j) dxm++;
5778: /* Local index in X dir */
5779: tmp = *dxm++ - starts[0];
5780: /* Loop over remaining dimensions */
5781: for (j = 0; j < dim-1; ++j) {
5782: /* If nonlocal, set index to be negative */
5783: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5784: /* Update local index */
5785: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5786: }
5787: /* Skip component slot if necessary */
5788: if (mat->stencil.noc) dxm++;
5789: /* Local row number */
5790: if (tmp >= 0) {
5791: jdxm[numNewRows++] = tmp;
5792: }
5793: }
5794: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5795: PetscFree(jdxm);
5796: return(0);
5797: }
5801: /*@C
5802: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5803: of a set of rows and columns of a matrix.
5805: Collective on Mat
5807: Input Parameters:
5808: + mat - the matrix
5809: . numRows - the number of rows/columns to remove
5810: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5811: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5812: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5813: - b - optional vector of right hand side, that will be adjusted by provided solution
5815: Notes:
5816: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5817: but does not release memory. For the dense and block diagonal
5818: formats this does not alter the nonzero structure.
5820: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5821: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5822: merely zeroed.
5824: The user can set a value in the diagonal entry (or for the AIJ and
5825: row formats can optionally remove the main diagonal entry from the
5826: nonzero structure as well, by passing 0.0 as the final argument).
5828: For the parallel case, all processes that share the matrix (i.e.,
5829: those in the communicator used for matrix creation) MUST call this
5830: routine, regardless of whether any rows being zeroed are owned by
5831: them.
5833: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5834: list only rows local to itself, but the row/column numbers are given in local numbering).
5836: The grid coordinates are across the entire grid, not just the local portion
5838: In Fortran idxm and idxn should be declared as
5839: $ MatStencil idxm(4,m)
5840: and the values inserted using
5841: $ idxm(MatStencil_i,1) = i
5842: $ idxm(MatStencil_j,1) = j
5843: $ idxm(MatStencil_k,1) = k
5844: $ idxm(MatStencil_c,1) = c
5845: etc
5847: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5848: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5849: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5850: DM_BOUNDARY_PERIODIC boundary type.
5852: 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
5853: a single value per point) you can skip filling those indices.
5855: Level: intermediate
5857: Concepts: matrices^zeroing rows
5859: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5860: @*/
5861: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5862: {
5863: PetscInt dim = mat->stencil.dim;
5864: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5865: PetscInt *dims = mat->stencil.dims+1;
5866: PetscInt *starts = mat->stencil.starts;
5867: PetscInt *dxm = (PetscInt*) rows;
5868: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5876: PetscMalloc1(numRows, &jdxm);
5877: for (i = 0; i < numRows; ++i) {
5878: /* Skip unused dimensions (they are ordered k, j, i, c) */
5879: for (j = 0; j < 3-sdim; ++j) dxm++;
5880: /* Local index in X dir */
5881: tmp = *dxm++ - starts[0];
5882: /* Loop over remaining dimensions */
5883: for (j = 0; j < dim-1; ++j) {
5884: /* If nonlocal, set index to be negative */
5885: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5886: /* Update local index */
5887: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5888: }
5889: /* Skip component slot if necessary */
5890: if (mat->stencil.noc) dxm++;
5891: /* Local row number */
5892: if (tmp >= 0) {
5893: jdxm[numNewRows++] = tmp;
5894: }
5895: }
5896: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5897: PetscFree(jdxm);
5898: return(0);
5899: }
5903: /*@C
5904: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5905: of a set of rows of a matrix; using local numbering of rows.
5907: Collective on Mat
5909: Input Parameters:
5910: + mat - the matrix
5911: . numRows - the number of rows to remove
5912: . rows - the global row indices
5913: . diag - value put in all diagonals of eliminated rows
5914: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5915: - b - optional vector of right hand side, that will be adjusted by provided solution
5917: Notes:
5918: Before calling MatZeroRowsLocal(), the user must first set the
5919: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5921: For the AIJ matrix formats this removes the old nonzero structure,
5922: but does not release memory. For the dense and block diagonal
5923: formats this does not alter the nonzero structure.
5925: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5926: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5927: merely zeroed.
5929: The user can set a value in the diagonal entry (or for the AIJ and
5930: row formats can optionally remove the main diagonal entry from the
5931: nonzero structure as well, by passing 0.0 as the final argument).
5933: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5934: owns that are to be zeroed. This saves a global synchronization in the implementation.
5936: Level: intermediate
5938: Concepts: matrices^zeroing
5940: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5941: @*/
5942: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5943: {
5950: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5951: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5952: MatCheckPreallocated(mat,1);
5954: if (mat->ops->zerorowslocal) {
5955: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5956: } else {
5957: IS is, newis;
5958: const PetscInt *newRows;
5960: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5961: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5962: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5963: ISGetIndices(newis,&newRows);
5964: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5965: ISRestoreIndices(newis,&newRows);
5966: ISDestroy(&newis);
5967: ISDestroy(&is);
5968: }
5969: PetscObjectStateIncrease((PetscObject)mat);
5970: #if defined(PETSC_HAVE_CUSP)
5971: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5972: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5973: }
5974: #endif
5975: #if defined(PETSC_HAVE_VIENNACL)
5976: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5977: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5978: }
5979: #endif
5980: return(0);
5981: }
5985: /*@C
5986: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5987: of a set of rows of a matrix; using local numbering of rows.
5989: Collective on Mat
5991: Input Parameters:
5992: + mat - the matrix
5993: . is - index set of rows to remove
5994: . diag - value put in all diagonals of eliminated rows
5995: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5996: - b - optional vector of right hand side, that will be adjusted by provided solution
5998: Notes:
5999: Before calling MatZeroRowsLocalIS(), the user must first set the
6000: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6002: For the AIJ matrix formats this removes the old nonzero structure,
6003: but does not release memory. For the dense and block diagonal
6004: formats this does not alter the nonzero structure.
6006: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6007: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6008: merely zeroed.
6010: The user can set a value in the diagonal entry (or for the AIJ and
6011: row formats can optionally remove the main diagonal entry from the
6012: nonzero structure as well, by passing 0.0 as the final argument).
6014: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6015: owns that are to be zeroed. This saves a global synchronization in the implementation.
6017: Level: intermediate
6019: Concepts: matrices^zeroing
6021: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6022: @*/
6023: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6024: {
6026: PetscInt numRows;
6027: const PetscInt *rows;
6033: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6034: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6035: MatCheckPreallocated(mat,1);
6037: ISGetLocalSize(is,&numRows);
6038: ISGetIndices(is,&rows);
6039: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6040: ISRestoreIndices(is,&rows);
6041: return(0);
6042: }
6046: /*@C
6047: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6048: of a set of rows and columns of a matrix; using local numbering of rows.
6050: Collective on Mat
6052: Input Parameters:
6053: + mat - the matrix
6054: . numRows - the number of rows to remove
6055: . rows - the global row indices
6056: . diag - value put in all diagonals of eliminated rows
6057: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6058: - b - optional vector of right hand side, that will be adjusted by provided solution
6060: Notes:
6061: Before calling MatZeroRowsColumnsLocal(), the user must first set the
6062: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6064: The user can set a value in the diagonal entry (or for the AIJ and
6065: row formats can optionally remove the main diagonal entry from the
6066: nonzero structure as well, by passing 0.0 as the final argument).
6068: Level: intermediate
6070: Concepts: matrices^zeroing
6072: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6073: @*/
6074: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6075: {
6077: IS is, newis;
6078: const PetscInt *newRows;
6084: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6085: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6086: MatCheckPreallocated(mat,1);
6088: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6089: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6090: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6091: ISGetIndices(newis,&newRows);
6092: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6093: ISRestoreIndices(newis,&newRows);
6094: ISDestroy(&newis);
6095: ISDestroy(&is);
6096: PetscObjectStateIncrease((PetscObject)mat);
6097: #if defined(PETSC_HAVE_CUSP)
6098: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6099: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6100: }
6101: #endif
6102: #if defined(PETSC_HAVE_VIENNACL)
6103: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6104: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6105: }
6106: #endif
6107: return(0);
6108: }
6112: /*@C
6113: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6114: of a set of rows and columns of a matrix; using local numbering of rows.
6116: Collective on Mat
6118: Input Parameters:
6119: + mat - the matrix
6120: . is - index set of rows to remove
6121: . diag - value put in all diagonals of eliminated rows
6122: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6123: - b - optional vector of right hand side, that will be adjusted by provided solution
6125: Notes:
6126: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6127: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6129: The user can set a value in the diagonal entry (or for the AIJ and
6130: row formats can optionally remove the main diagonal entry from the
6131: nonzero structure as well, by passing 0.0 as the final argument).
6133: Level: intermediate
6135: Concepts: matrices^zeroing
6137: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6138: @*/
6139: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6140: {
6142: PetscInt numRows;
6143: const PetscInt *rows;
6149: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6150: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6151: MatCheckPreallocated(mat,1);
6153: ISGetLocalSize(is,&numRows);
6154: ISGetIndices(is,&rows);
6155: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6156: ISRestoreIndices(is,&rows);
6157: return(0);
6158: }
6162: /*@
6163: MatGetSize - Returns the numbers of rows and columns in a matrix.
6165: Not Collective
6167: Input Parameter:
6168: . mat - the matrix
6170: Output Parameters:
6171: + m - the number of global rows
6172: - n - the number of global columns
6174: Note: both output parameters can be NULL on input.
6176: Level: beginner
6178: Concepts: matrices^size
6180: .seealso: MatGetLocalSize()
6181: @*/
6182: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6183: {
6186: if (m) *m = mat->rmap->N;
6187: if (n) *n = mat->cmap->N;
6188: return(0);
6189: }
6193: /*@
6194: MatGetLocalSize - Returns the number of rows and columns in a matrix
6195: stored locally. This information may be implementation dependent, so
6196: use with care.
6198: Not Collective
6200: Input Parameters:
6201: . mat - the matrix
6203: Output Parameters:
6204: + m - the number of local rows
6205: - n - the number of local columns
6207: Note: both output parameters can be NULL on input.
6209: Level: beginner
6211: Concepts: matrices^local size
6213: .seealso: MatGetSize()
6214: @*/
6215: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6216: {
6221: if (m) *m = mat->rmap->n;
6222: if (n) *n = mat->cmap->n;
6223: return(0);
6224: }
6228: /*@
6229: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6230: this processor. (The columns of the "diagonal block")
6232: Not Collective, unless matrix has not been allocated, then collective on Mat
6234: Input Parameters:
6235: . mat - the matrix
6237: Output Parameters:
6238: + m - the global index of the first local column
6239: - n - one more than the global index of the last local column
6241: Notes: both output parameters can be NULL on input.
6243: Level: developer
6245: Concepts: matrices^column ownership
6247: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6249: @*/
6250: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6251: {
6257: MatCheckPreallocated(mat,1);
6258: if (m) *m = mat->cmap->rstart;
6259: if (n) *n = mat->cmap->rend;
6260: return(0);
6261: }
6265: /*@
6266: MatGetOwnershipRange - Returns the range of matrix rows owned by
6267: this processor, assuming that the matrix is laid out with the first
6268: n1 rows on the first processor, the next n2 rows on the second, etc.
6269: For certain parallel layouts this range may not be well defined.
6271: Not Collective
6273: Input Parameters:
6274: . mat - the matrix
6276: Output Parameters:
6277: + m - the global index of the first local row
6278: - n - one more than the global index of the last local row
6280: Note: Both output parameters can be NULL on input.
6281: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6282: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6283: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6285: Level: beginner
6287: Concepts: matrices^row ownership
6289: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6291: @*/
6292: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6293: {
6299: MatCheckPreallocated(mat,1);
6300: if (m) *m = mat->rmap->rstart;
6301: if (n) *n = mat->rmap->rend;
6302: return(0);
6303: }
6307: /*@C
6308: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6309: each process
6311: Not Collective, unless matrix has not been allocated, then collective on Mat
6313: Input Parameters:
6314: . mat - the matrix
6316: Output Parameters:
6317: . ranges - start of each processors portion plus one more then the total length at the end
6319: Level: beginner
6321: Concepts: matrices^row ownership
6323: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6325: @*/
6326: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6327: {
6333: MatCheckPreallocated(mat,1);
6334: PetscLayoutGetRanges(mat->rmap,ranges);
6335: return(0);
6336: }
6340: /*@C
6341: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6342: this processor. (The columns of the "diagonal blocks" for each process)
6344: Not Collective, unless matrix has not been allocated, then collective on Mat
6346: Input Parameters:
6347: . mat - the matrix
6349: Output Parameters:
6350: . ranges - start of each processors portion plus one more then the total length at the end
6352: Level: beginner
6354: Concepts: matrices^column ownership
6356: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6358: @*/
6359: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6360: {
6366: MatCheckPreallocated(mat,1);
6367: PetscLayoutGetRanges(mat->cmap,ranges);
6368: return(0);
6369: }
6373: /*@C
6374: MatGetOwnershipIS - Get row and column ownership as index sets
6376: Not Collective
6378: Input Arguments:
6379: . A - matrix of type Elemental
6381: Output Arguments:
6382: + rows - rows in which this process owns elements
6383: . cols - columns in which this process owns elements
6385: Level: intermediate
6387: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6388: @*/
6389: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6390: {
6391: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6394: MatCheckPreallocated(A,1);
6395: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6396: if (f) {
6397: (*f)(A,rows,cols);
6398: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6399: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6400: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6401: }
6402: return(0);
6403: }
6407: /*@C
6408: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6409: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6410: to complete the factorization.
6412: Collective on Mat
6414: Input Parameters:
6415: + mat - the matrix
6416: . row - row permutation
6417: . column - column permutation
6418: - info - structure containing
6419: $ levels - number of levels of fill.
6420: $ expected fill - as ratio of original fill.
6421: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6422: missing diagonal entries)
6424: Output Parameters:
6425: . fact - new matrix that has been symbolically factored
6427: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6429: Most users should employ the simplified KSP interface for linear solvers
6430: instead of working directly with matrix algebra routines such as this.
6431: See, e.g., KSPCreate().
6433: Level: developer
6435: Concepts: matrices^symbolic LU factorization
6436: Concepts: matrices^factorization
6437: Concepts: LU^symbolic factorization
6439: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6440: MatGetOrdering(), MatFactorInfo
6442: Developer Note: fortran interface is not autogenerated as the f90
6443: interface defintion cannot be generated correctly [due to MatFactorInfo]
6445: @*/
6446: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6447: {
6457: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6458: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6459: if (!(fact)->ops->ilufactorsymbolic) {
6460: const MatSolverPackage spackage;
6461: MatFactorGetSolverPackage(fact,&spackage);
6462: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6463: }
6464: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6465: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6466: MatCheckPreallocated(mat,2);
6468: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6469: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6470: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6471: return(0);
6472: }
6476: /*@C
6477: MatICCFactorSymbolic - Performs symbolic incomplete
6478: Cholesky factorization for a symmetric matrix. Use
6479: MatCholeskyFactorNumeric() to complete the factorization.
6481: Collective on Mat
6483: Input Parameters:
6484: + mat - the matrix
6485: . perm - row and column permutation
6486: - info - structure containing
6487: $ levels - number of levels of fill.
6488: $ expected fill - as ratio of original fill.
6490: Output Parameter:
6491: . fact - the factored matrix
6493: Notes:
6494: Most users should employ the KSP interface for linear solvers
6495: instead of working directly with matrix algebra routines such as this.
6496: See, e.g., KSPCreate().
6498: Level: developer
6500: Concepts: matrices^symbolic incomplete Cholesky factorization
6501: Concepts: matrices^factorization
6502: Concepts: Cholsky^symbolic factorization
6504: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6506: Developer Note: fortran interface is not autogenerated as the f90
6507: interface defintion cannot be generated correctly [due to MatFactorInfo]
6509: @*/
6510: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6511: {
6520: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6521: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6522: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6523: if (!(fact)->ops->iccfactorsymbolic) {
6524: const MatSolverPackage spackage;
6525: MatFactorGetSolverPackage(fact,&spackage);
6526: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6527: }
6528: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6529: MatCheckPreallocated(mat,2);
6531: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6532: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6533: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6534: return(0);
6535: }
6539: /*@C
6540: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6541: points to an array of valid matrices, they may be reused to store the new
6542: submatrices.
6544: Collective on Mat
6546: Input Parameters:
6547: + mat - the matrix
6548: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6549: . irow, icol - index sets of rows and columns to extract
6550: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6552: Output Parameter:
6553: . submat - the array of submatrices
6555: Notes:
6556: MatGetSubMatrices() can extract ONLY sequential submatrices
6557: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6558: to extract a parallel submatrix.
6560: Some matrix types place restrictions on the row and column
6561: indices, such as that they be sorted or that they be equal to each other.
6563: The index sets may not have duplicate entries.
6565: When extracting submatrices from a parallel matrix, each processor can
6566: form a different submatrix by setting the rows and columns of its
6567: individual index sets according to the local submatrix desired.
6569: When finished using the submatrices, the user should destroy
6570: them with MatDestroyMatrices().
6572: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6573: original matrix has not changed from that last call to MatGetSubMatrices().
6575: This routine creates the matrices in submat; you should NOT create them before
6576: calling it. It also allocates the array of matrix pointers submat.
6578: For BAIJ matrices the index sets must respect the block structure, that is if they
6579: request one row/column in a block, they must request all rows/columns that are in
6580: that block. For example, if the block size is 2 you cannot request just row 0 and
6581: column 0.
6583: Fortran Note:
6584: The Fortran interface is slightly different from that given below; it
6585: requires one to pass in as submat a Mat (integer) array of size at least m.
6587: Level: advanced
6589: Concepts: matrices^accessing submatrices
6590: Concepts: submatrices
6592: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6593: @*/
6594: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6595: {
6597: PetscInt i;
6598: PetscBool eq;
6603: if (n) {
6608: }
6610: if (n && scall == MAT_REUSE_MATRIX) {
6613: }
6614: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6615: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6616: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6617: MatCheckPreallocated(mat,1);
6619: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6620: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6621: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6622: for (i=0; i<n; i++) {
6623: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6624: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6625: ISEqual(irow[i],icol[i],&eq);
6626: if (eq) {
6627: if (mat->symmetric) {
6628: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6629: } else if (mat->hermitian) {
6630: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6631: } else if (mat->structurally_symmetric) {
6632: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6633: }
6634: }
6635: }
6636: }
6637: return(0);
6638: }
6642: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6643: {
6645: PetscInt i;
6646: PetscBool eq;
6651: if (n) {
6656: }
6658: if (n && scall == MAT_REUSE_MATRIX) {
6661: }
6662: if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6663: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6664: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6665: MatCheckPreallocated(mat,1);
6667: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6668: (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6669: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6670: for (i=0; i<n; i++) {
6671: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6672: ISEqual(irow[i],icol[i],&eq);
6673: if (eq) {
6674: if (mat->symmetric) {
6675: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6676: } else if (mat->hermitian) {
6677: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6678: } else if (mat->structurally_symmetric) {
6679: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6680: }
6681: }
6682: }
6683: }
6684: return(0);
6685: }
6689: /*@C
6690: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6692: Collective on Mat
6694: Input Parameters:
6695: + n - the number of local matrices
6696: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6697: sequence of MatGetSubMatrices())
6699: Level: advanced
6701: Notes: Frees not only the matrices, but also the array that contains the matrices
6702: In Fortran will not free the array.
6704: .seealso: MatGetSubMatrices()
6705: @*/
6706: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6707: {
6709: PetscInt i;
6712: if (!*mat) return(0);
6713: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6715: for (i=0; i<n; i++) {
6716: MatDestroy(&(*mat)[i]);
6717: }
6718: /* memory is allocated even if n = 0 */
6719: PetscFree(*mat);
6720: *mat = NULL;
6721: return(0);
6722: }
6726: /*@C
6727: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6729: Collective on Mat
6731: Input Parameters:
6732: . mat - the matrix
6734: Output Parameter:
6735: . matstruct - the sequential matrix with the nonzero structure of mat
6737: Level: intermediate
6739: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6740: @*/
6741: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6742: {
6750: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6751: MatCheckPreallocated(mat,1);
6753: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6754: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6755: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6756: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6757: return(0);
6758: }
6762: /*@C
6763: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6765: Collective on Mat
6767: Input Parameters:
6768: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6769: sequence of MatGetSequentialNonzeroStructure())
6771: Level: advanced
6773: Notes: Frees not only the matrices, but also the array that contains the matrices
6775: .seealso: MatGetSeqNonzeroStructure()
6776: @*/
6777: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6778: {
6783: MatDestroy(mat);
6784: return(0);
6785: }
6789: /*@
6790: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6791: replaces the index sets by larger ones that represent submatrices with
6792: additional overlap.
6794: Collective on Mat
6796: Input Parameters:
6797: + mat - the matrix
6798: . n - the number of index sets
6799: . is - the array of index sets (these index sets will changed during the call)
6800: - ov - the additional overlap requested
6802: Level: developer
6804: Concepts: overlap
6805: Concepts: ASM^computing overlap
6807: .seealso: MatGetSubMatrices()
6808: @*/
6809: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6810: {
6816: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6817: if (n) {
6820: }
6821: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6822: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6823: MatCheckPreallocated(mat,1);
6825: if (!ov) return(0);
6826: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6827: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6828: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6829: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6830: return(0);
6831: }
6835: /*@
6836: MatGetBlockSize - Returns the matrix block size.
6838: Not Collective
6840: Input Parameter:
6841: . mat - the matrix
6843: Output Parameter:
6844: . bs - block size
6846: Notes:
6847: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6849: If the block size has not been set yet this routine returns 1.
6851: Level: intermediate
6853: Concepts: matrices^block size
6855: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6856: @*/
6857: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6858: {
6862: *bs = PetscAbs(mat->rmap->bs);
6863: return(0);
6864: }
6868: /*@
6869: MatGetBlockSizes - Returns the matrix block row and column sizes.
6871: Not Collective
6873: Input Parameter:
6874: . mat - the matrix
6876: Output Parameter:
6877: . rbs - row block size
6878: . cbs - coumn block size
6880: Notes:
6881: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6882: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
6884: If a block size has not been set yet this routine returns 1.
6886: Level: intermediate
6888: Concepts: matrices^block size
6890: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
6891: @*/
6892: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6893: {
6898: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
6899: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
6900: return(0);
6901: }
6905: /*@
6906: MatSetBlockSize - Sets the matrix block size.
6908: Logically Collective on Mat
6910: Input Parameters:
6911: + mat - the matrix
6912: - bs - block size
6914: Notes:
6915: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6917: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6919: Level: intermediate
6921: Concepts: matrices^block size
6923: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
6924: @*/
6925: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6926: {
6932: PetscLayoutSetBlockSize(mat->rmap,bs);
6933: PetscLayoutSetBlockSize(mat->cmap,bs);
6934: return(0);
6935: }
6939: /*@
6940: MatSetBlockSizes - Sets the matrix block row and column sizes.
6942: Logically Collective on Mat
6944: Input Parameters:
6945: + mat - the matrix
6946: - rbs - row block size
6947: - cbs - column block size
6949: Notes:
6950: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
6951: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
6953: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6955: The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
6957: Level: intermediate
6959: Concepts: matrices^block size
6961: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
6962: @*/
6963: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6964: {
6971: PetscLayoutSetBlockSize(mat->rmap,rbs);
6972: PetscLayoutSetBlockSize(mat->cmap,cbs);
6973: return(0);
6974: }
6978: /*@
6979: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
6981: Logically Collective on Mat
6983: Input Parameters:
6984: + mat - the matrix
6985: . fromRow - matrix from which to copy row block size
6986: - fromCol - matrix from which to copy column block size (can be same as fromRow)
6988: Level: developer
6990: Concepts: matrices^block size
6992: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
6993: @*/
6994: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
6995: {
7002: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7003: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7004: return(0);
7005: }
7009: /*@
7010: MatResidual - Default routine to calculate the residual.
7012: Collective on Mat and Vec
7014: Input Parameters:
7015: + mat - the matrix
7016: . b - the right-hand-side
7017: - x - the approximate solution
7019: Output Parameter:
7020: . r - location to store the residual
7022: Level: developer
7024: .keywords: MG, default, multigrid, residual
7026: .seealso: PCMGSetResidual()
7027: @*/
7028: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7029: {
7038: MatCheckPreallocated(mat,1);
7039: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7040: if (!mat->ops->residual) {
7041: MatMult(mat,x,r);
7042: VecAYPX(r,-1.0,b);
7043: } else {
7044: (*mat->ops->residual)(mat,b,x,r);
7045: }
7046: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7047: return(0);
7048: }
7052: /*@C
7053: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7055: Collective on Mat
7057: Input Parameters:
7058: + mat - the matrix
7059: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7060: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7061: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7062: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7063: always used.
7065: Output Parameters:
7066: + n - number of rows in the (possibly compressed) matrix
7067: . ia - the row pointers [of length n+1]
7068: . ja - the column indices
7069: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7070: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7072: Level: developer
7074: Notes: You CANNOT change any of the ia[] or ja[] values.
7076: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7078: Fortran Node
7080: In Fortran use
7081: $ PetscInt ia(1), ja(1)
7082: $ PetscOffset iia, jja
7083: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7084: $
7085: $ or
7086: $
7087: $ PetscScalar, pointer :: xx_v(:)
7088: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7091: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7093: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7094: @*/
7095: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7096: {
7106: MatCheckPreallocated(mat,1);
7107: if (!mat->ops->getrowij) *done = PETSC_FALSE;
7108: else {
7109: *done = PETSC_TRUE;
7110: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7111: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7112: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7113: }
7114: return(0);
7115: }
7119: /*@C
7120: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7122: Collective on Mat
7124: Input Parameters:
7125: + mat - the matrix
7126: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7127: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7128: symmetrized
7129: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7130: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7131: always used.
7132: . n - number of columns in the (possibly compressed) matrix
7133: . ia - the column pointers
7134: - ja - the row indices
7136: Output Parameters:
7137: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7139: Note:
7140: This routine zeros out n, ia, and ja. This is to prevent accidental
7141: us of the array after it has been restored. If you pass NULL, it will
7142: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
7144: Level: developer
7146: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7147: @*/
7148: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7149: {
7159: MatCheckPreallocated(mat,1);
7160: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7161: else {
7162: *done = PETSC_TRUE;
7163: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7164: }
7165: return(0);
7166: }
7170: /*@C
7171: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7172: MatGetRowIJ().
7174: Collective on Mat
7176: Input Parameters:
7177: + mat - the matrix
7178: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7179: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7180: symmetrized
7181: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7182: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7183: always used.
7184: . n - size of (possibly compressed) matrix
7185: . ia - the row pointers
7186: - ja - the column indices
7188: Output Parameters:
7189: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7191: Note:
7192: This routine zeros out n, ia, and ja. This is to prevent accidental
7193: us of the array after it has been restored. If you pass NULL, it will
7194: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7196: Level: developer
7198: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7199: @*/
7200: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7201: {
7210: MatCheckPreallocated(mat,1);
7212: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7213: else {
7214: *done = PETSC_TRUE;
7215: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7216: if (n) *n = 0;
7217: if (ia) *ia = NULL;
7218: if (ja) *ja = NULL;
7219: }
7220: return(0);
7221: }
7225: /*@C
7226: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7227: MatGetColumnIJ().
7229: Collective on Mat
7231: Input Parameters:
7232: + mat - the matrix
7233: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7234: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7235: symmetrized
7236: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7237: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7238: always used.
7240: Output Parameters:
7241: + n - size of (possibly compressed) matrix
7242: . ia - the column pointers
7243: . ja - the row indices
7244: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7246: Level: developer
7248: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7249: @*/
7250: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7251: {
7260: MatCheckPreallocated(mat,1);
7262: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7263: else {
7264: *done = PETSC_TRUE;
7265: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7266: if (n) *n = 0;
7267: if (ia) *ia = NULL;
7268: if (ja) *ja = NULL;
7269: }
7270: return(0);
7271: }
7275: /*@C
7276: MatColoringPatch -Used inside matrix coloring routines that
7277: use MatGetRowIJ() and/or MatGetColumnIJ().
7279: Collective on Mat
7281: Input Parameters:
7282: + mat - the matrix
7283: . ncolors - max color value
7284: . n - number of entries in colorarray
7285: - colorarray - array indicating color for each column
7287: Output Parameters:
7288: . iscoloring - coloring generated using colorarray information
7290: Level: developer
7292: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7294: @*/
7295: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7296: {
7304: MatCheckPreallocated(mat,1);
7306: if (!mat->ops->coloringpatch) {
7307: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7308: } else {
7309: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7310: }
7311: return(0);
7312: }
7317: /*@
7318: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7320: Logically Collective on Mat
7322: Input Parameter:
7323: . mat - the factored matrix to be reset
7325: Notes:
7326: This routine should be used only with factored matrices formed by in-place
7327: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7328: format). This option can save memory, for example, when solving nonlinear
7329: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7330: ILU(0) preconditioner.
7332: Note that one can specify in-place ILU(0) factorization by calling
7333: .vb
7334: PCType(pc,PCILU);
7335: PCFactorSeUseInPlace(pc);
7336: .ve
7337: or by using the options -pc_type ilu -pc_factor_in_place
7339: In-place factorization ILU(0) can also be used as a local
7340: solver for the blocks within the block Jacobi or additive Schwarz
7341: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7342: for details on setting local solver options.
7344: Most users should employ the simplified KSP interface for linear solvers
7345: instead of working directly with matrix algebra routines such as this.
7346: See, e.g., KSPCreate().
7348: Level: developer
7350: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7352: Concepts: matrices^unfactored
7354: @*/
7355: PetscErrorCode MatSetUnfactored(Mat mat)
7356: {
7362: MatCheckPreallocated(mat,1);
7363: mat->factortype = MAT_FACTOR_NONE;
7364: if (!mat->ops->setunfactored) return(0);
7365: (*mat->ops->setunfactored)(mat);
7366: return(0);
7367: }
7369: /*MC
7370: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7372: Synopsis:
7373: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7375: Not collective
7377: Input Parameter:
7378: . x - matrix
7380: Output Parameters:
7381: + xx_v - the Fortran90 pointer to the array
7382: - ierr - error code
7384: Example of Usage:
7385: .vb
7386: PetscScalar, pointer xx_v(:,:)
7387: ....
7388: call MatDenseGetArrayF90(x,xx_v,ierr)
7389: a = xx_v(3)
7390: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7391: .ve
7393: Level: advanced
7395: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7397: Concepts: matrices^accessing array
7399: M*/
7401: /*MC
7402: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7403: accessed with MatDenseGetArrayF90().
7405: Synopsis:
7406: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7408: Not collective
7410: Input Parameters:
7411: + x - matrix
7412: - xx_v - the Fortran90 pointer to the array
7414: Output Parameter:
7415: . ierr - error code
7417: Example of Usage:
7418: .vb
7419: PetscScalar, pointer xx_v(:)
7420: ....
7421: call MatDenseGetArrayF90(x,xx_v,ierr)
7422: a = xx_v(3)
7423: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7424: .ve
7426: Level: advanced
7428: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7430: M*/
7433: /*MC
7434: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7436: Synopsis:
7437: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7439: Not collective
7441: Input Parameter:
7442: . x - matrix
7444: Output Parameters:
7445: + xx_v - the Fortran90 pointer to the array
7446: - ierr - error code
7448: Example of Usage:
7449: .vb
7450: PetscScalar, pointer xx_v(:,:)
7451: ....
7452: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7453: a = xx_v(3)
7454: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7455: .ve
7457: Level: advanced
7459: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7461: Concepts: matrices^accessing array
7463: M*/
7465: /*MC
7466: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7467: accessed with MatSeqAIJGetArrayF90().
7469: Synopsis:
7470: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7472: Not collective
7474: Input Parameters:
7475: + x - matrix
7476: - xx_v - the Fortran90 pointer to the array
7478: Output Parameter:
7479: . ierr - error code
7481: Example of Usage:
7482: .vb
7483: PetscScalar, pointer xx_v(:)
7484: ....
7485: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7486: a = xx_v(3)
7487: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7488: .ve
7490: Level: advanced
7492: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7494: M*/
7499: /*@
7500: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7501: as the original matrix.
7503: Collective on Mat
7505: Input Parameters:
7506: + mat - the original matrix
7507: . isrow - parallel IS containing the rows this processor should obtain
7508: . 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.
7509: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7511: Output Parameter:
7512: . newmat - the new submatrix, of the same type as the old
7514: Level: advanced
7516: Notes:
7517: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7519: Some matrix types place restrictions on the row and column indices, such
7520: as that they be sorted or that they be equal to each other.
7522: The index sets may not have duplicate entries.
7524: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7525: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7526: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7527: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7528: you are finished using it.
7530: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7531: the input matrix.
7533: If iscol is NULL then all columns are obtained (not supported in Fortran).
7535: Example usage:
7536: Consider the following 8x8 matrix with 34 non-zero values, that is
7537: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7538: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7539: as follows:
7541: .vb
7542: 1 2 0 | 0 3 0 | 0 4
7543: Proc0 0 5 6 | 7 0 0 | 8 0
7544: 9 0 10 | 11 0 0 | 12 0
7545: -------------------------------------
7546: 13 0 14 | 15 16 17 | 0 0
7547: Proc1 0 18 0 | 19 20 21 | 0 0
7548: 0 0 0 | 22 23 0 | 24 0
7549: -------------------------------------
7550: Proc2 25 26 27 | 0 0 28 | 29 0
7551: 30 0 0 | 31 32 33 | 0 34
7552: .ve
7554: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7556: .vb
7557: 2 0 | 0 3 0 | 0
7558: Proc0 5 6 | 7 0 0 | 8
7559: -------------------------------
7560: Proc1 18 0 | 19 20 21 | 0
7561: -------------------------------
7562: Proc2 26 27 | 0 0 28 | 29
7563: 0 0 | 31 32 33 | 0
7564: .ve
7567: Concepts: matrices^submatrices
7569: .seealso: MatGetSubMatrices()
7570: @*/
7571: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7572: {
7574: PetscMPIInt size;
7575: Mat *local;
7576: IS iscoltmp;
7585: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7586: if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7588: MatCheckPreallocated(mat,1);
7589: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7591: if (!iscol || isrow == iscol) {
7592: PetscBool stride;
7593: PetscMPIInt grabentirematrix = 0,grab;
7594: PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7595: if (stride) {
7596: PetscInt first,step,n,rstart,rend;
7597: ISStrideGetInfo(isrow,&first,&step);
7598: if (step == 1) {
7599: MatGetOwnershipRange(mat,&rstart,&rend);
7600: if (rstart == first) {
7601: ISGetLocalSize(isrow,&n);
7602: if (n == rend-rstart) {
7603: grabentirematrix = 1;
7604: }
7605: }
7606: }
7607: }
7608: MPI_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7609: if (grab) {
7610: PetscInfo(mat,"Getting entire matrix as submatrix\n");
7611: if (cll == MAT_INITIAL_MATRIX) {
7612: *newmat = mat;
7613: PetscObjectReference((PetscObject)mat);
7614: }
7615: return(0);
7616: }
7617: }
7619: if (!iscol) {
7620: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7621: } else {
7622: iscoltmp = iscol;
7623: }
7625: /* if original matrix is on just one processor then use submatrix generated */
7626: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7627: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7628: if (!iscol) {ISDestroy(&iscoltmp);}
7629: return(0);
7630: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7631: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7632: *newmat = *local;
7633: PetscFree(local);
7634: if (!iscol) {ISDestroy(&iscoltmp);}
7635: return(0);
7636: } else if (!mat->ops->getsubmatrix) {
7637: /* Create a new matrix type that implements the operation using the full matrix */
7638: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7639: switch (cll) {
7640: case MAT_INITIAL_MATRIX:
7641: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7642: break;
7643: case MAT_REUSE_MATRIX:
7644: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7645: break;
7646: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7647: }
7648: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7649: if (!iscol) {ISDestroy(&iscoltmp);}
7650: return(0);
7651: }
7653: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7654: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7655: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7656: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7657: if (!iscol) {ISDestroy(&iscoltmp);}
7658: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7659: return(0);
7660: }
7664: /*@
7665: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7666: used during the assembly process to store values that belong to
7667: other processors.
7669: Not Collective
7671: Input Parameters:
7672: + mat - the matrix
7673: . size - the initial size of the stash.
7674: - bsize - the initial size of the block-stash(if used).
7676: Options Database Keys:
7677: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7678: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7680: Level: intermediate
7682: Notes:
7683: The block-stash is used for values set with MatSetValuesBlocked() while
7684: the stash is used for values set with MatSetValues()
7686: Run with the option -info and look for output of the form
7687: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7688: to determine the appropriate value, MM, to use for size and
7689: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7690: to determine the value, BMM to use for bsize
7692: Concepts: stash^setting matrix size
7693: Concepts: matrices^stash
7695: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7697: @*/
7698: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7699: {
7705: MatStashSetInitialSize_Private(&mat->stash,size);
7706: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7707: return(0);
7708: }
7712: /*@
7713: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7714: the matrix
7716: Neighbor-wise Collective on Mat
7718: Input Parameters:
7719: + mat - the matrix
7720: . x,y - the vectors
7721: - w - where the result is stored
7723: Level: intermediate
7725: Notes:
7726: w may be the same vector as y.
7728: This allows one to use either the restriction or interpolation (its transpose)
7729: matrix to do the interpolation
7731: Concepts: interpolation
7733: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7735: @*/
7736: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7737: {
7739: PetscInt M,N,Ny;
7747: MatCheckPreallocated(A,1);
7748: MatGetSize(A,&M,&N);
7749: VecGetSize(y,&Ny);
7750: if (M == Ny) {
7751: MatMultAdd(A,x,y,w);
7752: } else {
7753: MatMultTransposeAdd(A,x,y,w);
7754: }
7755: return(0);
7756: }
7760: /*@
7761: MatInterpolate - y = A*x or A'*x depending on the shape of
7762: the matrix
7764: Neighbor-wise Collective on Mat
7766: Input Parameters:
7767: + mat - the matrix
7768: - x,y - the vectors
7770: Level: intermediate
7772: Notes:
7773: This allows one to use either the restriction or interpolation (its transpose)
7774: matrix to do the interpolation
7776: Concepts: matrices^interpolation
7778: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7780: @*/
7781: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7782: {
7784: PetscInt M,N,Ny;
7791: MatCheckPreallocated(A,1);
7792: MatGetSize(A,&M,&N);
7793: VecGetSize(y,&Ny);
7794: if (M == Ny) {
7795: MatMult(A,x,y);
7796: } else {
7797: MatMultTranspose(A,x,y);
7798: }
7799: return(0);
7800: }
7804: /*@
7805: MatRestrict - y = A*x or A'*x
7807: Neighbor-wise Collective on Mat
7809: Input Parameters:
7810: + mat - the matrix
7811: - x,y - the vectors
7813: Level: intermediate
7815: Notes:
7816: This allows one to use either the restriction or interpolation (its transpose)
7817: matrix to do the restriction
7819: Concepts: matrices^restriction
7821: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7823: @*/
7824: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7825: {
7827: PetscInt M,N,Ny;
7834: MatCheckPreallocated(A,1);
7836: MatGetSize(A,&M,&N);
7837: VecGetSize(y,&Ny);
7838: if (M == Ny) {
7839: MatMult(A,x,y);
7840: } else {
7841: MatMultTranspose(A,x,y);
7842: }
7843: return(0);
7844: }
7848: /*@
7849: MatGetNullSpace - retrieves the null space to a matrix.
7851: Logically Collective on Mat and MatNullSpace
7853: Input Parameters:
7854: + mat - the matrix
7855: - nullsp - the null space object
7857: Level: developer
7859: Concepts: null space^attaching to matrix
7861: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
7862: @*/
7863: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7864: {
7869: *nullsp = mat->nullsp;
7870: return(0);
7871: }
7875: /*@
7876: MatSetNullSpace - attaches a null space to a matrix.
7878: Logically Collective on Mat and MatNullSpace
7880: Input Parameters:
7881: + mat - the matrix
7882: - nullsp - the null space object
7884: Level: advanced
7886: Notes:
7887: This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
7889: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
7890: call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
7893: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7894: the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
7895: Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
7896: n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
7897: the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
7899: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
7901: Concepts: null space^attaching to matrix
7903: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
7904: @*/
7905: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7906: {
7913: MatCheckPreallocated(mat,1);
7914: PetscObjectReference((PetscObject)nullsp);
7915: MatNullSpaceDestroy(&mat->nullsp);
7916: mat->nullsp = nullsp;
7917: return(0);
7918: }
7922: /*@
7923: MatGetTransposeNullSpace - retrieves the null space to a matrix.
7925: Logically Collective on Mat and MatNullSpace
7927: Input Parameters:
7928: + mat - the matrix
7929: - nullsp - the null space object
7931: Level: developer
7933: Notes:
7934: This null space is used by solvers. Overwrites any previous null space that may have been attached
7936: Concepts: null space^attaching to matrix
7938: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7939: @*/
7940: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
7941: {
7946: *nullsp = mat->transnullsp;
7947: return(0);
7948: }
7952: /*@
7953: MatSetTransposeNullSpace - attaches a null space to a matrix.
7955: Logically Collective on Mat and MatNullSpace
7957: Input Parameters:
7958: + mat - the matrix
7959: - nullsp - the null space object
7961: Level: advanced
7963: Notes:
7964: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
7965: You must also call MatSetNullSpace()
7968: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
7969: the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
7970: Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
7971: n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
7972: the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
7974: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
7976: Concepts: null space^attaching to matrix
7978: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetNullSpace(), MatNullSpaceRemove()
7979: @*/
7980: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
7981: {
7988: MatCheckPreallocated(mat,1);
7989: PetscObjectReference((PetscObject)nullsp);
7990: MatNullSpaceDestroy(&mat->transnullsp);
7991: mat->transnullsp = nullsp;
7992: return(0);
7993: }
7997: /*@
7998: MatSetNearNullSpace - attaches a null space to a matrix.
7999: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8001: Logically Collective on Mat and MatNullSpace
8003: Input Parameters:
8004: + mat - the matrix
8005: - nullsp - the null space object
8007: Level: advanced
8009: Notes:
8010: Overwrites any previous near null space that may have been attached
8012: Concepts: null space^attaching to matrix
8014: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
8015: @*/
8016: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8017: {
8024: MatCheckPreallocated(mat,1);
8025: PetscObjectReference((PetscObject)nullsp);
8026: MatNullSpaceDestroy(&mat->nearnullsp);
8028: mat->nearnullsp = nullsp;
8029: return(0);
8030: }
8034: /*@
8035: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8037: Not Collective
8039: Input Parameters:
8040: . mat - the matrix
8042: Output Parameters:
8043: . nullsp - the null space object, NULL if not set
8045: Level: developer
8047: Concepts: null space^attaching to matrix
8049: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
8050: @*/
8051: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8052: {
8057: MatCheckPreallocated(mat,1);
8058: *nullsp = mat->nearnullsp;
8059: return(0);
8060: }
8064: /*@C
8065: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8067: Collective on Mat
8069: Input Parameters:
8070: + mat - the matrix
8071: . row - row/column permutation
8072: . fill - expected fill factor >= 1.0
8073: - level - level of fill, for ICC(k)
8075: Notes:
8076: Probably really in-place only when level of fill is zero, otherwise allocates
8077: new space to store factored matrix and deletes previous memory.
8079: Most users should employ the simplified KSP interface for linear solvers
8080: instead of working directly with matrix algebra routines such as this.
8081: See, e.g., KSPCreate().
8083: Level: developer
8085: Concepts: matrices^incomplete Cholesky factorization
8086: Concepts: Cholesky factorization
8088: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8090: Developer Note: fortran interface is not autogenerated as the f90
8091: interface defintion cannot be generated correctly [due to MatFactorInfo]
8093: @*/
8094: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8095: {
8103: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8104: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8105: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8106: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8107: MatCheckPreallocated(mat,1);
8108: (*mat->ops->iccfactor)(mat,row,info);
8109: PetscObjectStateIncrease((PetscObject)mat);
8110: return(0);
8111: }
8115: /*@
8116: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8118: Not Collective
8120: Input Parameters:
8121: + mat - the matrix
8122: . nl - leading dimension of v
8123: - v - the values compute with ADIFOR
8125: Level: developer
8127: Notes:
8128: Must call MatSetColoring() before using this routine. Also this matrix must already
8129: have its nonzero pattern determined.
8131: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8132: MatSetValues(), MatSetColoring()
8133: @*/
8134: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8135: {
8143: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8144: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8145: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8146: (*mat->ops->setvaluesadifor)(mat,nl,v);
8147: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8148: PetscObjectStateIncrease((PetscObject)mat);
8149: return(0);
8150: }
8154: /*@
8155: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8156: ghosted ones.
8158: Not Collective
8160: Input Parameters:
8161: + mat - the matrix
8162: - diag = the diagonal values, including ghost ones
8164: Level: developer
8166: Notes: Works only for MPIAIJ and MPIBAIJ matrices
8168: .seealso: MatDiagonalScale()
8169: @*/
8170: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8171: {
8173: PetscMPIInt size;
8180: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8181: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8182: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8183: if (size == 1) {
8184: PetscInt n,m;
8185: VecGetSize(diag,&n);
8186: MatGetSize(mat,0,&m);
8187: if (m == n) {
8188: MatDiagonalScale(mat,0,diag);
8189: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8190: } else {
8191: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8192: }
8193: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8194: PetscObjectStateIncrease((PetscObject)mat);
8195: return(0);
8196: }
8200: /*@
8201: MatGetInertia - Gets the inertia from a factored matrix
8203: Collective on Mat
8205: Input Parameter:
8206: . mat - the matrix
8208: Output Parameters:
8209: + nneg - number of negative eigenvalues
8210: . nzero - number of zero eigenvalues
8211: - npos - number of positive eigenvalues
8213: Level: advanced
8215: Notes: Matrix must have been factored by MatCholeskyFactor()
8218: @*/
8219: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8220: {
8226: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8227: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8228: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8229: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8230: return(0);
8231: }
8233: /* ----------------------------------------------------------------*/
8236: /*@C
8237: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8239: Neighbor-wise Collective on Mat and Vecs
8241: Input Parameters:
8242: + mat - the factored matrix
8243: - b - the right-hand-side vectors
8245: Output Parameter:
8246: . x - the result vectors
8248: Notes:
8249: The vectors b and x cannot be the same. I.e., one cannot
8250: call MatSolves(A,x,x).
8252: Notes:
8253: Most users should employ the simplified KSP interface for linear solvers
8254: instead of working directly with matrix algebra routines such as this.
8255: See, e.g., KSPCreate().
8257: Level: developer
8259: Concepts: matrices^triangular solves
8261: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8262: @*/
8263: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8264: {
8270: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8271: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8272: if (!mat->rmap->N && !mat->cmap->N) return(0);
8274: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8275: MatCheckPreallocated(mat,1);
8276: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8277: (*mat->ops->solves)(mat,b,x);
8278: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8279: return(0);
8280: }
8284: /*@
8285: MatIsSymmetric - Test whether a matrix is symmetric
8287: Collective on Mat
8289: Input Parameter:
8290: + A - the matrix to test
8291: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8293: Output Parameters:
8294: . flg - the result
8296: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8298: Level: intermediate
8300: Concepts: matrix^symmetry
8302: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8303: @*/
8304: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8305: {
8312: if (!A->symmetric_set) {
8313: if (!A->ops->issymmetric) {
8314: MatType mattype;
8315: MatGetType(A,&mattype);
8316: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8317: }
8318: (*A->ops->issymmetric)(A,tol,flg);
8319: if (!tol) {
8320: A->symmetric_set = PETSC_TRUE;
8321: A->symmetric = *flg;
8322: if (A->symmetric) {
8323: A->structurally_symmetric_set = PETSC_TRUE;
8324: A->structurally_symmetric = PETSC_TRUE;
8325: }
8326: }
8327: } else if (A->symmetric) {
8328: *flg = PETSC_TRUE;
8329: } else if (!tol) {
8330: *flg = PETSC_FALSE;
8331: } else {
8332: if (!A->ops->issymmetric) {
8333: MatType mattype;
8334: MatGetType(A,&mattype);
8335: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8336: }
8337: (*A->ops->issymmetric)(A,tol,flg);
8338: }
8339: return(0);
8340: }
8344: /*@
8345: MatIsHermitian - Test whether a matrix is Hermitian
8347: Collective on Mat
8349: Input Parameter:
8350: + A - the matrix to test
8351: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8353: Output Parameters:
8354: . flg - the result
8356: Level: intermediate
8358: Concepts: matrix^symmetry
8360: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8361: MatIsSymmetricKnown(), MatIsSymmetric()
8362: @*/
8363: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8364: {
8371: if (!A->hermitian_set) {
8372: if (!A->ops->ishermitian) {
8373: MatType mattype;
8374: MatGetType(A,&mattype);
8375: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8376: }
8377: (*A->ops->ishermitian)(A,tol,flg);
8378: if (!tol) {
8379: A->hermitian_set = PETSC_TRUE;
8380: A->hermitian = *flg;
8381: if (A->hermitian) {
8382: A->structurally_symmetric_set = PETSC_TRUE;
8383: A->structurally_symmetric = PETSC_TRUE;
8384: }
8385: }
8386: } else if (A->hermitian) {
8387: *flg = PETSC_TRUE;
8388: } else if (!tol) {
8389: *flg = PETSC_FALSE;
8390: } else {
8391: if (!A->ops->ishermitian) {
8392: MatType mattype;
8393: MatGetType(A,&mattype);
8394: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8395: }
8396: (*A->ops->ishermitian)(A,tol,flg);
8397: }
8398: return(0);
8399: }
8403: /*@
8404: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8406: Not Collective
8408: Input Parameter:
8409: . A - the matrix to check
8411: Output Parameters:
8412: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8413: - flg - the result
8415: Level: advanced
8417: Concepts: matrix^symmetry
8419: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8420: if you want it explicitly checked
8422: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8423: @*/
8424: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8425: {
8430: if (A->symmetric_set) {
8431: *set = PETSC_TRUE;
8432: *flg = A->symmetric;
8433: } else {
8434: *set = PETSC_FALSE;
8435: }
8436: return(0);
8437: }
8441: /*@
8442: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8444: Not Collective
8446: Input Parameter:
8447: . A - the matrix to check
8449: Output Parameters:
8450: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8451: - flg - the result
8453: Level: advanced
8455: Concepts: matrix^symmetry
8457: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8458: if you want it explicitly checked
8460: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8461: @*/
8462: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8463: {
8468: if (A->hermitian_set) {
8469: *set = PETSC_TRUE;
8470: *flg = A->hermitian;
8471: } else {
8472: *set = PETSC_FALSE;
8473: }
8474: return(0);
8475: }
8479: /*@
8480: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8482: Collective on Mat
8484: Input Parameter:
8485: . A - the matrix to test
8487: Output Parameters:
8488: . flg - the result
8490: Level: intermediate
8492: Concepts: matrix^symmetry
8494: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8495: @*/
8496: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8497: {
8503: if (!A->structurally_symmetric_set) {
8504: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8505: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8507: A->structurally_symmetric_set = PETSC_TRUE;
8508: }
8509: *flg = A->structurally_symmetric;
8510: return(0);
8511: }
8515: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8516: /*@
8517: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8518: to be communicated to other processors during the MatAssemblyBegin/End() process
8520: Not collective
8522: Input Parameter:
8523: . vec - the vector
8525: Output Parameters:
8526: + nstash - the size of the stash
8527: . reallocs - the number of additional mallocs incurred.
8528: . bnstash - the size of the block stash
8529: - breallocs - the number of additional mallocs incurred.in the block stash
8531: Level: advanced
8533: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8535: @*/
8536: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8537: {
8541: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8542: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8543: return(0);
8544: }
8548: /*@C
8549: MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8550: parallel layout
8552: Collective on Mat
8554: Input Parameter:
8555: . mat - the matrix
8557: Output Parameter:
8558: + right - (optional) vector that the matrix can be multiplied against
8559: - left - (optional) vector that the matrix vector product can be stored in
8561: Notes:
8562: The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().
8564: Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8566: Level: advanced
8568: .seealso: MatCreate(), VecDestroy()
8569: @*/
8570: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8571: {
8577: MatCheckPreallocated(mat,1);
8578: if (mat->ops->getvecs) {
8579: (*mat->ops->getvecs)(mat,right,left);
8580: } else {
8581: PetscMPIInt size;
8582: PetscInt rbs,cbs;
8583: MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8584: MatGetBlockSizes(mat,&rbs,&cbs);
8585: if (right) {
8586: VecCreate(PetscObjectComm((PetscObject)mat),right);
8587: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8588: VecSetBlockSize(*right,cbs);
8589: VecSetType(*right,VECSTANDARD);
8590: PetscLayoutReference(mat->cmap,&(*right)->map);
8591: }
8592: if (left) {
8593: VecCreate(PetscObjectComm((PetscObject)mat),left);
8594: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8595: VecSetBlockSize(*left,rbs);
8596: VecSetType(*left,VECSTANDARD);
8597: PetscLayoutReference(mat->rmap,&(*left)->map);
8598: }
8599: }
8600: return(0);
8601: }
8605: /*@C
8606: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8607: with default values.
8609: Not Collective
8611: Input Parameters:
8612: . info - the MatFactorInfo data structure
8615: Notes: The solvers are generally used through the KSP and PC objects, for example
8616: PCLU, PCILU, PCCHOLESKY, PCICC
8618: Level: developer
8620: .seealso: MatFactorInfo
8622: Developer Note: fortran interface is not autogenerated as the f90
8623: interface defintion cannot be generated correctly [due to MatFactorInfo]
8625: @*/
8627: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8628: {
8632: PetscMemzero(info,sizeof(MatFactorInfo));
8633: return(0);
8634: }
8638: /*@
8639: MatPtAP - Creates the matrix product C = P^T * A * P
8641: Neighbor-wise Collective on Mat
8643: Input Parameters:
8644: + A - the matrix
8645: . P - the projection matrix
8646: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8647: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8649: Output Parameters:
8650: . C - the product matrix
8652: Notes:
8653: C will be created and must be destroyed by the user with MatDestroy().
8655: This routine is currently only implemented for pairs of AIJ matrices and classes
8656: which inherit from AIJ.
8658: Level: intermediate
8660: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8661: @*/
8662: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8663: {
8665: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8666: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8667: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8668: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8671: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8672: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
8676: MatCheckPreallocated(A,1);
8677: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8678: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8681: MatCheckPreallocated(P,2);
8682: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8683: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8685: 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);
8686: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8688: if (scall == MAT_REUSE_MATRIX) {
8691: if (viatranspose || viamatmatmatmult) {
8692: Mat Pt;
8693: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8694: if (viamatmatmatmult) {
8695: MatMatMatMult(Pt,A,P,scall,fill,C);
8696: } else {
8697: Mat AP;
8698: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8699: MatMatMult(Pt,AP,scall,fill,C);
8700: MatDestroy(&AP);
8701: }
8702: MatDestroy(&Pt);
8703: } else {
8704: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8705: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8706: (*(*C)->ops->ptapnumeric)(A,P,*C);
8707: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8708: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8709: }
8710: return(0);
8711: }
8713: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8714: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8716: fA = A->ops->ptap;
8717: fP = P->ops->ptap;
8718: if (fP == fA) {
8719: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8720: ptap = fA;
8721: } else {
8722: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8723: char ptapname[256];
8724: PetscStrcpy(ptapname,"MatPtAP_");
8725: PetscStrcat(ptapname,((PetscObject)A)->type_name);
8726: PetscStrcat(ptapname,"_");
8727: PetscStrcat(ptapname,((PetscObject)P)->type_name);
8728: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8729: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8730: 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);
8731: }
8733: if (viatranspose || viamatmatmatmult) {
8734: Mat Pt;
8735: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8736: if (viamatmatmatmult) {
8737: MatMatMatMult(Pt,A,P,scall,fill,C);
8738: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8739: } else {
8740: Mat AP;
8741: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8742: MatMatMult(Pt,AP,scall,fill,C);
8743: MatDestroy(&AP);
8744: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8745: }
8746: MatDestroy(&Pt);
8747: } else {
8748: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8749: (*ptap)(A,P,scall,fill,C);
8750: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8751: }
8752: return(0);
8753: }
8757: /*@
8758: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8760: Neighbor-wise Collective on Mat
8762: Input Parameters:
8763: + A - the matrix
8764: - P - the projection matrix
8766: Output Parameters:
8767: . C - the product matrix
8769: Notes:
8770: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8771: the user using MatDeatroy().
8773: This routine is currently only implemented for pairs of AIJ matrices and classes
8774: which inherit from AIJ. C will be of type MATAIJ.
8776: Level: intermediate
8778: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8779: @*/
8780: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8781: {
8787: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8788: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8791: MatCheckPreallocated(P,2);
8792: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8793: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8796: MatCheckPreallocated(C,3);
8797: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8798: 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);
8799: 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);
8800: 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);
8801: 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);
8802: MatCheckPreallocated(A,1);
8804: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8805: (*C->ops->ptapnumeric)(A,P,C);
8806: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8807: return(0);
8808: }
8812: /*@
8813: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8815: Neighbor-wise Collective on Mat
8817: Input Parameters:
8818: + A - the matrix
8819: - P - the projection matrix
8821: Output Parameters:
8822: . C - the (i,j) structure of the product matrix
8824: Notes:
8825: C will be created and must be destroyed by the user with MatDestroy().
8827: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8828: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8829: this (i,j) structure by calling MatPtAPNumeric().
8831: Level: intermediate
8833: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8834: @*/
8835: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8836: {
8842: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8843: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8844: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8847: MatCheckPreallocated(P,2);
8848: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8849: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8852: 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);
8853: 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);
8854: MatCheckPreallocated(A,1);
8855: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8856: (*A->ops->ptapsymbolic)(A,P,fill,C);
8857: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8859: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8860: return(0);
8861: }
8865: /*@
8866: MatRARt - Creates the matrix product C = R * A * R^T
8868: Neighbor-wise Collective on Mat
8870: Input Parameters:
8871: + A - the matrix
8872: . R - the projection matrix
8873: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8874: - fill - expected fill as ratio of nnz(C)/nnz(A)
8876: Output Parameters:
8877: . C - the product matrix
8879: Notes:
8880: C will be created and must be destroyed by the user with MatDestroy().
8882: This routine is currently only implemented for pairs of AIJ matrices and classes
8883: which inherit from AIJ.
8885: Level: intermediate
8887: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8888: @*/
8889: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8890: {
8896: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8897: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8900: MatCheckPreallocated(R,2);
8901: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8902: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8904: 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);
8905: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
8906: MatCheckPreallocated(A,1);
8908: if (!A->ops->rart) {
8909: MatType mattype;
8910: MatGetType(A,&mattype);
8911: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8912: }
8913: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8914: (*A->ops->rart)(A,R,scall,fill,C);
8915: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8916: return(0);
8917: }
8921: /*@
8922: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8924: Neighbor-wise Collective on Mat
8926: Input Parameters:
8927: + A - the matrix
8928: - R - the projection matrix
8930: Output Parameters:
8931: . C - the product matrix
8933: Notes:
8934: C must have been created by calling MatRARtSymbolic and must be destroyed by
8935: the user using MatDeatroy().
8937: This routine is currently only implemented for pairs of AIJ matrices and classes
8938: which inherit from AIJ. C will be of type MATAIJ.
8940: Level: intermediate
8942: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8943: @*/
8944: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8945: {
8951: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8952: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8955: MatCheckPreallocated(R,2);
8956: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8957: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8960: MatCheckPreallocated(C,3);
8961: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8962: 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);
8963: 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);
8964: 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);
8965: 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);
8966: MatCheckPreallocated(A,1);
8968: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8969: (*A->ops->rartnumeric)(A,R,C);
8970: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8971: return(0);
8972: }
8976: /*@
8977: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8979: Neighbor-wise Collective on Mat
8981: Input Parameters:
8982: + A - the matrix
8983: - R - the projection matrix
8985: Output Parameters:
8986: . C - the (i,j) structure of the product matrix
8988: Notes:
8989: C will be created and must be destroyed by the user with MatDestroy().
8991: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8992: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8993: this (i,j) structure by calling MatRARtNumeric().
8995: Level: intermediate
8997: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8998: @*/
8999: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9000: {
9006: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9007: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9008: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9011: MatCheckPreallocated(R,2);
9012: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9013: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9016: 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);
9017: 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);
9018: MatCheckPreallocated(A,1);
9019: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9020: (*A->ops->rartsymbolic)(A,R,fill,C);
9021: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9023: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9024: return(0);
9025: }
9029: /*@
9030: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9032: Neighbor-wise Collective on Mat
9034: Input Parameters:
9035: + A - the left matrix
9036: . B - the right matrix
9037: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9038: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9039: if the result is a dense matrix this is irrelevent
9041: Output Parameters:
9042: . C - the product matrix
9044: Notes:
9045: Unless scall is MAT_REUSE_MATRIX C will be created.
9047: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9049: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9050: actually needed.
9052: If you have many matrices with the same non-zero structure to multiply, you
9053: should either
9054: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9055: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9056: In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9057: with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9059: Level: intermediate
9061: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9062: @*/
9063: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9064: {
9066: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9067: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9068: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9073: MatCheckPreallocated(A,1);
9074: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9075: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9078: MatCheckPreallocated(B,2);
9079: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9080: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9082: 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);
9083: if (scall == MAT_REUSE_MATRIX) {
9086: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9087: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9088: (*(*C)->ops->matmultnumeric)(A,B,*C);
9089: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9090: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9091: return(0);
9092: }
9093: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9094: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9096: fA = A->ops->matmult;
9097: fB = B->ops->matmult;
9098: if (fB == fA) {
9099: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9100: mult = fB;
9101: } else {
9102: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9103: char multname[256];
9104: PetscStrcpy(multname,"MatMatMult_");
9105: PetscStrcat(multname,((PetscObject)A)->type_name);
9106: PetscStrcat(multname,"_");
9107: PetscStrcat(multname,((PetscObject)B)->type_name);
9108: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9109: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9110: 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);
9111: }
9112: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9113: (*mult)(A,B,scall,fill,C);
9114: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9115: return(0);
9116: }
9120: /*@
9121: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9122: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
9124: Neighbor-wise Collective on Mat
9126: Input Parameters:
9127: + A - the left matrix
9128: . B - the right matrix
9129: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9130: if C is a dense matrix this is irrelevent
9132: Output Parameters:
9133: . C - the product matrix
9135: Notes:
9136: Unless scall is MAT_REUSE_MATRIX C will be created.
9138: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9139: actually needed.
9141: This routine is currently implemented for
9142: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9143: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9144: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9146: Level: intermediate
9148: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9149: We should incorporate them into PETSc.
9151: .seealso: MatMatMult(), MatMatMultNumeric()
9152: @*/
9153: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9154: {
9156: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9157: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9158: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9163: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9164: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9168: MatCheckPreallocated(B,2);
9169: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9170: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9173: 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);
9174: if (fill == PETSC_DEFAULT) fill = 2.0;
9175: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9176: MatCheckPreallocated(A,1);
9178: Asymbolic = A->ops->matmultsymbolic;
9179: Bsymbolic = B->ops->matmultsymbolic;
9180: if (Asymbolic == Bsymbolic) {
9181: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9182: symbolic = Bsymbolic;
9183: } else { /* dispatch based on the type of A and B */
9184: char symbolicname[256];
9185: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9186: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9187: PetscStrcat(symbolicname,"_");
9188: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9189: PetscStrcat(symbolicname,"_C");
9190: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9191: 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);
9192: }
9193: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9194: (*symbolic)(A,B,fill,C);
9195: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9196: return(0);
9197: }
9201: /*@
9202: MatMatMultNumeric - Performs the numeric matrix-matrix product.
9203: Call this routine after first calling MatMatMultSymbolic().
9205: Neighbor-wise Collective on Mat
9207: Input Parameters:
9208: + A - the left matrix
9209: - B - the right matrix
9211: Output Parameters:
9212: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9214: Notes:
9215: C must have been created with MatMatMultSymbolic().
9217: This routine is currently implemented for
9218: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9219: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9220: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9222: Level: intermediate
9224: .seealso: MatMatMult(), MatMatMultSymbolic()
9225: @*/
9226: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9227: {
9231: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9232: return(0);
9233: }
9237: /*@
9238: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9240: Neighbor-wise Collective on Mat
9242: Input Parameters:
9243: + A - the left matrix
9244: . B - the right matrix
9245: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9246: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9248: Output Parameters:
9249: . C - the product matrix
9251: Notes:
9252: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9254: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9256: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9257: actually needed.
9259: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
9261: Level: intermediate
9263: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9264: @*/
9265: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9266: {
9268: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9269: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9274: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9275: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9278: MatCheckPreallocated(B,2);
9279: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9280: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9282: 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);
9283: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9284: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9285: MatCheckPreallocated(A,1);
9287: fA = A->ops->mattransposemult;
9288: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9289: fB = B->ops->mattransposemult;
9290: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9291: 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);
9293: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9294: if (scall == MAT_INITIAL_MATRIX) {
9295: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9296: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9297: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9298: }
9299: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9300: (*A->ops->mattransposemultnumeric)(A,B,*C);
9301: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9302: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9303: return(0);
9304: }
9308: /*@
9309: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9311: Neighbor-wise Collective on Mat
9313: Input Parameters:
9314: + A - the left matrix
9315: . B - the right matrix
9316: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9317: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9319: Output Parameters:
9320: . C - the product matrix
9322: Notes:
9323: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9325: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9327: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9328: actually needed.
9330: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9331: which inherit from SeqAIJ. C will be of same type as the input matrices.
9333: Level: intermediate
9335: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9336: @*/
9337: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9338: {
9340: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9341: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9342: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9347: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9348: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9351: MatCheckPreallocated(B,2);
9352: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9353: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9355: 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);
9356: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9357: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9358: MatCheckPreallocated(A,1);
9360: fA = A->ops->transposematmult;
9361: fB = B->ops->transposematmult;
9362: if (fB==fA) {
9363: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9364: transposematmult = fA;
9365: } else {
9366: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9367: char multname[256];
9368: PetscStrcpy(multname,"MatTransposeMatMult_");
9369: PetscStrcat(multname,((PetscObject)A)->type_name);
9370: PetscStrcat(multname,"_");
9371: PetscStrcat(multname,((PetscObject)B)->type_name);
9372: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9373: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9374: 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);
9375: }
9376: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9377: (*transposematmult)(A,B,scall,fill,C);
9378: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9379: return(0);
9380: }
9384: /*@
9385: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9387: Neighbor-wise Collective on Mat
9389: Input Parameters:
9390: + A - the left matrix
9391: . B - the middle matrix
9392: . C - the right matrix
9393: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9394: - 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
9395: if the result is a dense matrix this is irrelevent
9397: Output Parameters:
9398: . D - the product matrix
9400: Notes:
9401: Unless scall is MAT_REUSE_MATRIX D will be created.
9403: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9405: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9406: actually needed.
9408: If you have many matrices with the same non-zero structure to multiply, you
9409: should either
9410: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9411: $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
9413: Level: intermediate
9415: .seealso: MatMatMult, MatPtAP()
9416: @*/
9417: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9418: {
9420: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9421: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9422: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9423: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9428: MatCheckPreallocated(A,1);
9429: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9430: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9433: MatCheckPreallocated(B,2);
9434: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9435: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9438: MatCheckPreallocated(C,3);
9439: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9440: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9441: 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);
9442: 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);
9443: if (scall == MAT_REUSE_MATRIX) {
9446: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9447: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9448: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9449: return(0);
9450: }
9451: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9452: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9454: fA = A->ops->matmatmult;
9455: fB = B->ops->matmatmult;
9456: fC = C->ops->matmatmult;
9457: if (fA == fB && fA == fC) {
9458: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9459: mult = fA;
9460: } else {
9461: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9462: char multname[256];
9463: PetscStrcpy(multname,"MatMatMatMult_");
9464: PetscStrcat(multname,((PetscObject)A)->type_name);
9465: PetscStrcat(multname,"_");
9466: PetscStrcat(multname,((PetscObject)B)->type_name);
9467: PetscStrcat(multname,"_");
9468: PetscStrcat(multname,((PetscObject)C)->type_name);
9469: PetscStrcat(multname,"_C");
9470: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9471: 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);
9472: }
9473: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9474: (*mult)(A,B,C,scall,fill,D);
9475: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9476: return(0);
9477: }
9481: /*@C
9482: MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9484: Collective on Mat
9486: Input Parameters:
9487: + mat - the matrix
9488: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9489: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9490: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9492: Output Parameter:
9493: . matredundant - redundant matrix
9495: Notes:
9496: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9497: original matrix has not changed from that last call to MatCreateRedundantMatrix().
9499: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9500: calling it.
9502: Level: advanced
9504: Concepts: subcommunicator
9505: Concepts: duplicate matrix
9507: .seealso: MatDestroy()
9508: @*/
9509: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9510: {
9512: MPI_Comm comm;
9513: PetscMPIInt size;
9514: PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9515: Mat_Redundant *redund=NULL;
9516: PetscSubcomm psubcomm=NULL;
9517: MPI_Comm subcomm_in=subcomm;
9518: Mat *matseq;
9519: IS isrow,iscol;
9520: PetscBool newsubcomm=PETSC_FALSE;
9523: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9524: if (size == 1 || nsubcomm == 1) {
9525: if (reuse == MAT_INITIAL_MATRIX) {
9526: MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9527: } else {
9528: MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9529: }
9530: return(0);
9531: }
9534: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9537: }
9538: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9539: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9540: MatCheckPreallocated(mat,1);
9542: PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9543: if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9544: /* create psubcomm, then get subcomm */
9545: PetscObjectGetComm((PetscObject)mat,&comm);
9546: MPI_Comm_size(comm,&size);
9547: if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9549: PetscSubcommCreate(comm,&psubcomm);
9550: PetscSubcommSetNumber(psubcomm,nsubcomm);
9551: PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9552: PetscSubcommSetFromOptions(psubcomm);
9553: PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9554: newsubcomm = PETSC_TRUE;
9555: PetscSubcommDestroy(&psubcomm);
9556: }
9558: /* get isrow, iscol and a local sequential matrix matseq[0] */
9559: if (reuse == MAT_INITIAL_MATRIX) {
9560: mloc_sub = PETSC_DECIDE;
9561: if (bs < 1) {
9562: PetscSplitOwnership(subcomm,&mloc_sub,&M);
9563: } else {
9564: PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9565: }
9566: MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9567: rstart = rend - mloc_sub;
9568: ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9569: ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9570: } else { /* reuse == MAT_REUSE_MATRIX */
9571: /* retrieve subcomm */
9572: PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9573: redund = (*matredundant)->redundant;
9574: isrow = redund->isrow;
9575: iscol = redund->iscol;
9576: matseq = redund->matseq;
9577: }
9578: MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9580: /* get matredundant over subcomm */
9581: if (reuse == MAT_INITIAL_MATRIX) {
9582: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);
9584: /* create a supporting struct and attach it to C for reuse */
9585: PetscNewLog(*matredundant,&redund);
9586: (*matredundant)->redundant = redund;
9587: redund->isrow = isrow;
9588: redund->iscol = iscol;
9589: redund->matseq = matseq;
9590: if (newsubcomm) {
9591: redund->subcomm = subcomm;
9592: } else {
9593: redund->subcomm = MPI_COMM_NULL;
9594: }
9595: } else {
9596: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9597: }
9598: PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
9599: return(0);
9600: }
9604: /*@C
9605: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9606: a given 'mat' object. Each submatrix can span multiple procs.
9608: Collective on Mat
9610: Input Parameters:
9611: + mat - the matrix
9612: . subcomm - the subcommunicator obtained by com_split(comm)
9613: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9615: Output Parameter:
9616: . subMat - 'parallel submatrices each spans a given subcomm
9618: Notes:
9619: The submatrix partition across processors is dictated by 'subComm' a
9620: communicator obtained by com_split(comm). The comm_split
9621: is not restriced to be grouped with consecutive original ranks.
9623: Due the comm_split() usage, the parallel layout of the submatrices
9624: map directly to the layout of the original matrix [wrt the local
9625: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9626: into the 'DiagonalMat' of the subMat, hence it is used directly from
9627: the subMat. However the offDiagMat looses some columns - and this is
9628: reconstructed with MatSetValues()
9630: Level: advanced
9632: Concepts: subcommunicator
9633: Concepts: submatrices
9635: .seealso: MatGetSubMatrices()
9636: @*/
9637: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9638: {
9640: PetscMPIInt commsize,subCommSize;
9643: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9644: MPI_Comm_size(subComm,&subCommSize);
9645: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9647: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9648: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9649: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9650: return(0);
9651: }
9655: /*@
9656: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9658: Not Collective
9660: Input Arguments:
9661: mat - matrix to extract local submatrix from
9662: isrow - local row indices for submatrix
9663: iscol - local column indices for submatrix
9665: Output Arguments:
9666: submat - the submatrix
9668: Level: intermediate
9670: Notes:
9671: The submat should be returned with MatRestoreLocalSubMatrix().
9673: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9674: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9676: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9677: MatSetValuesBlockedLocal() will also be implemented.
9679: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9680: @*/
9681: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9682: {
9692: if (mat->ops->getlocalsubmatrix) {
9693: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9694: } else {
9695: MatCreateLocalRef(mat,isrow,iscol,submat);
9696: }
9697: return(0);
9698: }
9702: /*@
9703: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9705: Not Collective
9707: Input Arguments:
9708: mat - matrix to extract local submatrix from
9709: isrow - local row indices for submatrix
9710: iscol - local column indices for submatrix
9711: submat - the submatrix
9713: Level: intermediate
9715: .seealso: MatGetLocalSubMatrix()
9716: @*/
9717: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9718: {
9727: if (*submat) {
9729: }
9731: if (mat->ops->restorelocalsubmatrix) {
9732: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9733: } else {
9734: MatDestroy(submat);
9735: }
9736: *submat = NULL;
9737: return(0);
9738: }
9740: /* --------------------------------------------------------*/
9743: /*@
9744: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9746: Collective on Mat
9748: Input Parameter:
9749: . mat - the matrix
9751: Output Parameter:
9752: . is - if any rows have zero diagonals this contains the list of them
9754: Level: developer
9756: Concepts: matrix-vector product
9758: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9759: @*/
9760: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9761: {
9767: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9768: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9770: if (!mat->ops->findzerodiagonals) {
9771: Vec diag;
9772: const PetscScalar *a;
9773: PetscInt *rows;
9774: PetscInt rStart, rEnd, r, nrow = 0;
9776: MatCreateVecs(mat, &diag, NULL);
9777: MatGetDiagonal(mat, diag);
9778: MatGetOwnershipRange(mat, &rStart, &rEnd);
9779: VecGetArrayRead(diag, &a);
9780: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
9781: PetscMalloc1(nrow, &rows);
9782: nrow = 0;
9783: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
9784: VecRestoreArrayRead(diag, &a);
9785: VecDestroy(&diag);
9786: ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
9787: } else {
9788: (*mat->ops->findzerodiagonals)(mat, is);
9789: }
9790: return(0);
9791: }
9795: /*@
9796: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
9798: Collective on Mat
9800: Input Parameter:
9801: . mat - the matrix
9803: Output Parameter:
9804: . is - contains the list of rows with off block diagonal entries
9806: Level: developer
9808: Concepts: matrix-vector product
9810: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9811: @*/
9812: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
9813: {
9819: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9820: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9822: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
9823: (*mat->ops->findoffblockdiagonalentries)(mat,is);
9824: return(0);
9825: }
9829: /*@C
9830: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9832: Collective on Mat
9834: Input Parameters:
9835: . mat - the matrix
9837: Output Parameters:
9838: . values - the block inverses in column major order (FORTRAN-like)
9840: Note:
9841: This routine is not available from Fortran.
9843: Level: advanced
9844: @*/
9845: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9846: {
9851: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9852: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9853: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9854: (*mat->ops->invertblockdiagonal)(mat,values);
9855: return(0);
9856: }
9860: /*@C
9861: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9862: via MatTransposeColoringCreate().
9864: Collective on MatTransposeColoring
9866: Input Parameter:
9867: . c - coloring context
9869: Level: intermediate
9871: .seealso: MatTransposeColoringCreate()
9872: @*/
9873: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9874: {
9875: PetscErrorCode ierr;
9876: MatTransposeColoring matcolor=*c;
9879: if (!matcolor) return(0);
9880: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9882: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
9883: PetscFree(matcolor->rows);
9884: PetscFree(matcolor->den2sp);
9885: PetscFree(matcolor->colorforcol);
9886: PetscFree(matcolor->columns);
9887: if (matcolor->brows>0) {
9888: PetscFree(matcolor->lstart);
9889: }
9890: PetscHeaderDestroy(c);
9891: return(0);
9892: }
9896: /*@C
9897: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9898: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9899: MatTransposeColoring to sparse B.
9901: Collective on MatTransposeColoring
9903: Input Parameters:
9904: + B - sparse matrix B
9905: . Btdense - symbolic dense matrix B^T
9906: - coloring - coloring context created with MatTransposeColoringCreate()
9908: Output Parameter:
9909: . Btdense - dense matrix B^T
9911: Options Database Keys:
9912: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9913: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9914: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9916: Level: intermediate
9918: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9920: .keywords: coloring
9921: @*/
9922: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9923: {
9931: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9932: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9933: return(0);
9934: }
9938: /*@C
9939: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9940: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9941: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9942: Csp from Cden.
9944: Collective on MatTransposeColoring
9946: Input Parameters:
9947: + coloring - coloring context created with MatTransposeColoringCreate()
9948: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9950: Output Parameter:
9951: . Csp - sparse matrix
9953: Options Database Keys:
9954: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9955: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9956: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9958: Level: intermediate
9960: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9962: .keywords: coloring
9963: @*/
9964: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9965: {
9973: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9974: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9975: return(0);
9976: }
9980: /*@C
9981: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9983: Collective on Mat
9985: Input Parameters:
9986: + mat - the matrix product C
9987: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
9989: Output Parameter:
9990: . color - the new coloring context
9992: Level: intermediate
9994: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9995: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9996: @*/
9997: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9998: {
9999: MatTransposeColoring c;
10000: MPI_Comm comm;
10001: PetscErrorCode ierr;
10004: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10005: PetscObjectGetComm((PetscObject)mat,&comm);
10006: PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10008: c->ctype = iscoloring->ctype;
10009: if (mat->ops->transposecoloringcreate) {
10010: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10011: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10013: *color = c;
10014: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10015: return(0);
10016: }
10020: /*@
10021: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10022: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10023: same, otherwise it will be larger
10025: Not Collective
10027: Input Parameter:
10028: . A - the matrix
10030: Output Parameter:
10031: . state - the current state
10033: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10034: different matrices
10036: Level: intermediate
10038: @*/
10039: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10040: {
10043: *state = mat->nonzerostate;
10044: return(0);
10045: }
10049: /*@
10050: MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10051: matrices from each processor
10053: Collective on MPI_Comm
10055: Input Parameters:
10056: + comm - the communicators the parallel matrix will live on
10057: . seqmat - the input sequential matrices
10058: . n - number of local columns (or PETSC_DECIDE)
10059: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10061: Output Parameter:
10062: . mpimat - the parallel matrix generated
10064: Level: advanced
10066: Notes: The number of columns of the matrix in EACH processor MUST be the same.
10068: @*/
10069: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10070: {
10072: PetscMPIInt size;
10075: MPI_Comm_size(comm,&size);
10076: if (size == 1) {
10077: if (reuse == MAT_INITIAL_MATRIX) {
10078: MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10079: } else {
10080: MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10081: }
10082: return(0);
10083: }
10085: if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10086: PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10087: (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10088: PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10089: return(0);
10090: }
10094: /*@
10095: MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10096: ranks' ownership ranges.
10098: Collective on A
10100: Input Parameters:
10101: + A - the matrix to create subdomains from
10102: - N - requested number of subdomains
10105: Output Parameters:
10106: + n - number of subdomains resulting on this rank
10107: - iss - IS list with indices of subdomains on this rank
10109: Level: advanced
10111: Notes: number of subdomains must be smaller than the communicator size
10112: @*/
10113: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10114: {
10115: MPI_Comm comm,subcomm;
10116: PetscMPIInt size,rank,color,subsize,subrank;
10117: PetscInt rstart,rend,k;
10118: PetscErrorCode ierr;
10121: PetscObjectGetComm((PetscObject)A,&comm);
10122: MPI_Comm_size(comm,&size);
10123: MPI_Comm_rank(comm,&rank);
10124: if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10125: *n = 1;
10126: k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10127: color = rank/k;
10128: MPI_Comm_split(comm,color,rank,&subcomm);
10129: MPI_Comm_size(subcomm,&subsize);
10130: MPI_Comm_size(subcomm,&subrank);
10131: PetscMalloc1(1,iss);
10132: MatGetOwnershipRange(A,&rstart,&rend);
10133: ISCreateStride(subcomm,rend-rstart,rstart,1,*iss);
10134: return(0);
10135: }