Actual source code: matrix.c
petsc-3.4.5 2014-06-29
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc-private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc-private/vecimpl.h>
9: /* Logging support */
10: PetscClassId MAT_CLASSID;
11: PetscClassId MAT_FDCOLORING_CLASSID;
12: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
14: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
15: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
16: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
17: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
18: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
19: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetColoring, MAT_GetOrdering, MAT_GetRedundantMatrix, MAT_GetSeqNonzeroStructure;
20: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
21: PetscLogEvent MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction;
22: PetscLogEvent MAT_TransposeColoringCreate;
23: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
24: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
25: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
26: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
27: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
28: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
29: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
30: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
31: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
32: PetscLogEvent MAT_GetMultiProcBlock;
33: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
34: PetscLogEvent MAT_Merge;
36: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
40: /*@
41: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
43: Logically Collective on Vec
45: Input Parameters:
46: + x - the vector
47: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
48: it will create one internally.
50: Output Parameter:
51: . x - the vector
53: Example of Usage:
54: .vb
55: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
56: VecSetRandom(x,rctx);
57: PetscRandomDestroy(rctx);
58: .ve
60: Level: intermediate
62: Concepts: vector^setting to random
63: Concepts: random^vector
65: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
66: @*/
67: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
68: {
70: PetscRandom randObj = NULL;
77: if (!rctx) {
78: MPI_Comm comm;
79: PetscObjectGetComm((PetscObject)x,&comm);
80: PetscRandomCreate(comm,&randObj);
81: PetscRandomSetFromOptions(randObj);
82: rctx = randObj;
83: }
85: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
86: (*x->ops->setrandom)(x,rctx);
87: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
89: x->assembled = PETSC_TRUE;
90: PetscRandomDestroy(&randObj);
91: return(0);
92: }
97: /*@
98: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
100: Input Parameter:
101: . A - the matrix
103: Output Parameter:
104: . keptrows - the rows that are not completely zero
106: Level: intermediate
108: @*/
109: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
110: {
115: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
116: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
117: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
118: (*mat->ops->findnonzerorows)(mat,keptrows);
119: return(0);
120: }
124: /*@
125: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
127: Not Collective
129: Input Parameters:
130: . A - the matrix
132: Output Parameters:
133: . a - the diagonal part (which is a SEQUENTIAL matrix)
135: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
137: Level: advanced
139: @*/
140: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
141: {
142: PetscErrorCode ierr,(*f)(Mat,Mat*);
143: PetscMPIInt size;
149: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
150: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
151: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
152: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
153: if (f) {
154: (*f)(A,a);
155: return(0);
156: } else if (size == 1) {
157: *a = A;
158: } else {
159: MatType mattype;
160: MatGetType(A,&mattype);
161: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
162: }
163: return(0);
164: }
168: /*@
169: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
171: Collective on Mat
173: Input Parameters:
174: . mat - the matrix
176: Output Parameter:
177: . trace - the sum of the diagonal entries
179: Level: advanced
181: @*/
182: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
183: {
185: Vec diag;
188: MatGetVecs(mat,&diag,NULL);
189: MatGetDiagonal(mat,diag);
190: VecSum(diag,trace);
191: VecDestroy(&diag);
192: return(0);
193: }
197: /*@
198: MatRealPart - Zeros out the imaginary part of the matrix
200: Logically Collective on Mat
202: Input Parameters:
203: . mat - the matrix
205: Level: advanced
208: .seealso: MatImaginaryPart()
209: @*/
210: PetscErrorCode MatRealPart(Mat mat)
211: {
217: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
218: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
219: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
220: MatCheckPreallocated(mat,1);
221: (*mat->ops->realpart)(mat);
222: #if defined(PETSC_HAVE_CUSP)
223: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
224: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
225: }
226: #endif
227: return(0);
228: }
232: /*@C
233: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
235: Collective on Mat
237: Input Parameter:
238: . mat - the matrix
240: Output Parameters:
241: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
242: - ghosts - the global indices of the ghost points
244: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
246: Level: advanced
248: @*/
249: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
250: {
256: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
257: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
258: if (!mat->ops->getghosts) {
259: if (nghosts) *nghosts = 0;
260: if (ghosts) *ghosts = 0;
261: } else {
262: (*mat->ops->getghosts)(mat,nghosts,ghosts);
263: }
264: return(0);
265: }
270: /*@
271: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
273: Logically Collective on Mat
275: Input Parameters:
276: . mat - the matrix
278: Level: advanced
281: .seealso: MatRealPart()
282: @*/
283: PetscErrorCode MatImaginaryPart(Mat mat)
284: {
290: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
291: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
292: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
293: MatCheckPreallocated(mat,1);
294: (*mat->ops->imaginarypart)(mat);
295: #if defined(PETSC_HAVE_CUSP)
296: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
297: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
298: }
299: #endif
300: return(0);
301: }
305: /*@
306: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
308: Collective on Mat
310: Input Parameter:
311: . mat - the matrix
313: Output Parameters:
314: + missing - is any diagonal missing
315: - dd - first diagonal entry that is missing (optional)
317: Level: advanced
320: .seealso: MatRealPart()
321: @*/
322: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
323: {
329: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
330: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
331: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
332: (*mat->ops->missingdiagonal)(mat,missing,dd);
333: return(0);
334: }
338: /*@C
339: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
340: for each row that you get to ensure that your application does
341: not bleed memory.
343: Not Collective
345: Input Parameters:
346: + mat - the matrix
347: - row - the row to get
349: Output Parameters:
350: + ncols - if not NULL, the number of nonzeros in the row
351: . cols - if not NULL, the column numbers
352: - vals - if not NULL, the values
354: Notes:
355: This routine is provided for people who need to have direct access
356: to the structure of a matrix. We hope that we provide enough
357: high-level matrix routines that few users will need it.
359: MatGetRow() always returns 0-based column indices, regardless of
360: whether the internal representation is 0-based (default) or 1-based.
362: For better efficiency, set cols and/or vals to NULL if you do
363: not wish to extract these quantities.
365: The user can only examine the values extracted with MatGetRow();
366: the values cannot be altered. To change the matrix entries, one
367: must use MatSetValues().
369: You can only have one call to MatGetRow() outstanding for a particular
370: matrix at a time, per processor. MatGetRow() can only obtain rows
371: associated with the given processor, it cannot get rows from the
372: other processors; for that we suggest using MatGetSubMatrices(), then
373: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
374: is in the global number of rows.
376: Fortran Notes:
377: The calling sequence from Fortran is
378: .vb
379: MatGetRow(matrix,row,ncols,cols,values,ierr)
380: Mat matrix (input)
381: integer row (input)
382: integer ncols (output)
383: integer cols(maxcols) (output)
384: double precision (or double complex) values(maxcols) output
385: .ve
386: where maxcols >= maximum nonzeros in any row of the matrix.
389: Caution:
390: Do not try to change the contents of the output arrays (cols and vals).
391: In some cases, this may corrupt the matrix.
393: Level: advanced
395: Concepts: matrices^row access
397: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
398: @*/
399: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
400: {
402: PetscInt incols;
407: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
408: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
409: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
410: MatCheckPreallocated(mat,1);
411: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
412: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
413: if (ncols) *ncols = incols;
414: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
415: return(0);
416: }
420: /*@
421: MatConjugate - replaces the matrix values with their complex conjugates
423: Logically Collective on Mat
425: Input Parameters:
426: . mat - the matrix
428: Level: advanced
430: .seealso: VecConjugate()
431: @*/
432: PetscErrorCode MatConjugate(Mat mat)
433: {
434: #if defined(PETSC_USE_COMPLEX)
439: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
440: 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");
441: (*mat->ops->conjugate)(mat);
442: #if defined(PETSC_HAVE_CUSP)
443: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
444: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
445: }
446: #endif
447: return(0);
448: #else
449: return 0;
450: #endif
451: }
455: /*@C
456: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
458: Not Collective
460: Input Parameters:
461: + mat - the matrix
462: . row - the row to get
463: . ncols, cols - the number of nonzeros and their columns
464: - vals - if nonzero the column values
466: Notes:
467: This routine should be called after you have finished examining the entries.
469: Fortran Notes:
470: The calling sequence from Fortran is
471: .vb
472: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
473: Mat matrix (input)
474: integer row (input)
475: integer ncols (output)
476: integer cols(maxcols) (output)
477: double precision (or double complex) values(maxcols) output
478: .ve
479: Where maxcols >= maximum nonzeros in any row of the matrix.
481: In Fortran MatRestoreRow() MUST be called after MatGetRow()
482: before another call to MatGetRow() can be made.
484: Level: advanced
486: .seealso: MatGetRow()
487: @*/
488: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
489: {
495: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
496: if (!mat->ops->restorerow) return(0);
497: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
498: if (ncols) *ncols = 0;
499: if (cols) *cols = NULL;
500: if (vals) *vals = NULL;
501: return(0);
502: }
506: /*@
507: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
508: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
510: Not Collective
512: Input Parameters:
513: + mat - the matrix
515: Notes:
516: 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.
518: Level: advanced
520: Concepts: matrices^row access
522: .seealso: MatRestoreRowRowUpperTriangular()
523: @*/
524: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
525: {
531: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
532: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
533: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
534: MatCheckPreallocated(mat,1);
535: (*mat->ops->getrowuppertriangular)(mat);
536: return(0);
537: }
541: /*@
542: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
544: Not Collective
546: Input Parameters:
547: + mat - the matrix
549: Notes:
550: This routine should be called after you have finished MatGetRow/MatRestoreRow().
553: Level: advanced
555: .seealso: MatGetRowUpperTriangular()
556: @*/
557: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
558: {
563: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
564: if (!mat->ops->restorerowuppertriangular) return(0);
565: (*mat->ops->restorerowuppertriangular)(mat);
566: return(0);
567: }
571: /*@C
572: MatSetOptionsPrefix - Sets the prefix used for searching for all
573: Mat options in the database.
575: Logically Collective on Mat
577: Input Parameter:
578: + A - the Mat context
579: - prefix - the prefix to prepend to all option names
581: Notes:
582: A hyphen (-) must NOT be given at the beginning of the prefix name.
583: The first character of all runtime options is AUTOMATICALLY the hyphen.
585: Level: advanced
587: .keywords: Mat, set, options, prefix, database
589: .seealso: MatSetFromOptions()
590: @*/
591: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
592: {
597: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
598: return(0);
599: }
603: /*@C
604: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
605: Mat options in the database.
607: Logically Collective on Mat
609: Input Parameters:
610: + A - the Mat context
611: - prefix - the prefix to prepend to all option names
613: Notes:
614: A hyphen (-) must NOT be given at the beginning of the prefix name.
615: The first character of all runtime options is AUTOMATICALLY the hyphen.
617: Level: advanced
619: .keywords: Mat, append, options, prefix, database
621: .seealso: MatGetOptionsPrefix()
622: @*/
623: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
624: {
629: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
630: return(0);
631: }
635: /*@C
636: MatGetOptionsPrefix - Sets the prefix used for searching for all
637: Mat options in the database.
639: Not Collective
641: Input Parameter:
642: . A - the Mat context
644: Output Parameter:
645: . prefix - pointer to the prefix string used
647: Notes: On the fortran side, the user should pass in a string 'prefix' of
648: sufficient length to hold the prefix.
650: Level: advanced
652: .keywords: Mat, get, options, prefix, database
654: .seealso: MatAppendOptionsPrefix()
655: @*/
656: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
657: {
662: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
663: return(0);
664: }
668: /*@
669: MatSetUp - Sets up the internal matrix data structures for the later use.
671: Collective on Mat
673: Input Parameters:
674: . A - the Mat context
676: Notes:
677: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
679: If a suitable preallocation routine is used, this function does not need to be called.
681: See the Performance chapter of the PETSc users manual for how to preallocate matrices
683: Level: beginner
685: .keywords: Mat, setup
687: .seealso: MatCreate(), MatDestroy()
688: @*/
689: PetscErrorCode MatSetUp(Mat A)
690: {
691: PetscMPIInt size;
696: if (!((PetscObject)A)->type_name) {
697: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
698: if (size == 1) {
699: MatSetType(A, MATSEQAIJ);
700: } else {
701: MatSetType(A, MATMPIAIJ);
702: }
703: }
704: if (!A->preallocated && A->ops->setup) {
705: PetscInfo(A,"Warning not preallocating matrix storage\n");
706: (*A->ops->setup)(A);
707: }
708: A->preallocated = PETSC_TRUE;
709: return(0);
710: }
712: #if defined(PETSC_HAVE_AMS)
713: #include <petscviewerams.h>
714: #endif
717: /*@C
718: MatView - Visualizes a matrix object.
720: Collective on Mat
722: Input Parameters:
723: + mat - the matrix
724: - viewer - visualization context
726: Notes:
727: The available visualization contexts include
728: + PETSC_VIEWER_STDOUT_SELF - standard output (default)
729: . PETSC_VIEWER_STDOUT_WORLD - synchronized standard
730: output where only the first processor opens
731: the file. All other processors send their
732: data to the first processor to print.
733: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
735: The user can open alternative visualization contexts with
736: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
737: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
738: specified file; corresponding input uses MatLoad()
739: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
740: an X window display
741: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
742: Currently only the sequential dense and AIJ
743: matrix types support the Socket viewer.
745: The user can call PetscViewerSetFormat() to specify the output
746: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
747: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
748: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
749: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
750: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
751: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
752: format common among all matrix types
753: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
754: format (which is in many cases the same as the default)
755: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
756: size and structure (not the matrix entries)
757: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
758: the matrix structure
760: Options Database Keys:
761: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
762: . -mat_view ::ascii_info_detail - Prints more detailed info
763: . -mat_view - Prints matrix in ASCII format
764: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
765: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
766: . -display <name> - Sets display name (default is host)
767: . -draw_pause <sec> - Sets number of seconds to pause after display
768: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see the <a href="../../docs/manual.pdf">users manual</a> for details).
769: . -viewer_socket_machine <machine>
770: . -viewer_socket_port <port>
771: . -mat_view binary - save matrix to file in binary format
772: - -viewer_binary_filename <name>
773: Level: beginner
775: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
776: viewer is used.
778: See bin/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
779: viewer is used.
781: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
782: And then use the following mouse functions:
783: left mouse: zoom in
784: middle mouse: zoom out
785: right mouse: continue with the simulation
787: Concepts: matrices^viewing
788: Concepts: matrices^plotting
789: Concepts: matrices^printing
791: .seealso: PetscViewerSetFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
792: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
793: @*/
794: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
795: {
796: PetscErrorCode ierr;
797: PetscInt rows,cols,bs;
798: PetscBool iascii;
799: PetscViewerFormat format;
800: #if defined(PETSC_HAVE_AMS)
801: PetscBool isams;
802: #endif
807: if (!viewer) {
808: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
809: }
812: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
813: MatCheckPreallocated(mat,1);
815: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
816: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
817: #if defined(PETSC_HAVE_AMS)
818: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERAMS,&isams);
819: #endif
820: if (iascii) {
821: PetscViewerGetFormat(viewer,&format);
822: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
823: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer,"Matrix Object");
824: PetscViewerASCIIPushTab(viewer);
825: MatGetSize(mat,&rows,&cols);
826: MatGetBlockSize(mat,&bs);
827: if (bs != 1) {
828: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,bs);
829: } else {
830: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
831: }
832: if (mat->factortype) {
833: const MatSolverPackage solver;
834: MatFactorGetSolverPackage(mat,&solver);
835: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
836: }
837: if (mat->ops->getinfo) {
838: MatInfo info;
839: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
840: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%lld, allocated nonzeros=%lld\n",(Petsc64bitInt)info.nz_used,(Petsc64bitInt)info.nz_allocated);
841: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
842: }
843: }
844: #if defined(PETSC_HAVE_AMS)
845: } else if (isams) {
846: if (((PetscObject)mat)->amsmem == -1) {
847: PetscObjectViewAMS((PetscObject)mat,viewer);
848: }
849: #endif
850: }
851: if (mat->ops->view) {
852: PetscViewerASCIIPushTab(viewer);
853: (*mat->ops->view)(mat,viewer);
854: PetscViewerASCIIPopTab(viewer);
855: } else if (!iascii) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Viewer type %s not supported",((PetscObject)viewer)->type_name);
856: if (iascii) {
857: PetscViewerGetFormat(viewer,&format);
858: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
859: PetscViewerASCIIPopTab(viewer);
860: }
861: }
862: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
863: return(0);
864: }
866: #if defined(PETSC_USE_DEBUG)
867: #include <../src/sys/totalview/tv_data_display.h>
868: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
869: {
870: TV_add_row("Local rows", "int", &mat->rmap->n);
871: TV_add_row("Local columns", "int", &mat->cmap->n);
872: TV_add_row("Global rows", "int", &mat->rmap->N);
873: TV_add_row("Global columns", "int", &mat->cmap->N);
874: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
875: return TV_format_OK;
876: }
877: #endif
881: /*@C
882: MatLoad - Loads a matrix that has been stored in binary format
883: with MatView(). The matrix format is determined from the options database.
884: Generates a parallel MPI matrix if the communicator has more than one
885: processor. The default matrix type is AIJ.
887: Collective on PetscViewer
889: Input Parameters:
890: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
891: or some related function before a call to MatLoad()
892: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
894: Options Database Keys:
895: Used with block matrix formats (MATSEQBAIJ, ...) to specify
896: block size
897: . -matload_block_size <bs>
899: Level: beginner
901: Notes:
902: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
903: Mat before calling this routine if you wish to set it from the options database.
905: MatLoad() automatically loads into the options database any options
906: given in the file filename.info where filename is the name of the file
907: that was passed to the PetscViewerBinaryOpen(). The options in the info
908: file will be ignored if you use the -viewer_binary_skip_info option.
910: If the type or size of newmat is not set before a call to MatLoad, PETSc
911: sets the default matrix type AIJ and sets the local and global sizes.
912: If type and/or size is already set, then the same are used.
914: In parallel, each processor can load a subset of rows (or the
915: entire matrix). This routine is especially useful when a large
916: matrix is stored on disk and only part of it is desired on each
917: processor. For example, a parallel solver may access only some of
918: the rows from each processor. The algorithm used here reads
919: relatively small blocks of data rather than reading the entire
920: matrix and then subsetting it.
922: Notes for advanced users:
923: Most users should not need to know the details of the binary storage
924: format, since MatLoad() and MatView() completely hide these details.
925: But for anyone who's interested, the standard binary matrix storage
926: format is
928: $ int MAT_FILE_CLASSID
929: $ int number of rows
930: $ int number of columns
931: $ int total number of nonzeros
932: $ int *number nonzeros in each row
933: $ int *column indices of all nonzeros (starting index is zero)
934: $ PetscScalar *values of all nonzeros
936: PETSc automatically does the byte swapping for
937: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
938: linux, Windows and the paragon; thus if you write your own binary
939: read/write routines you have to swap the bytes; see PetscBinaryRead()
940: and PetscBinaryWrite() to see how this may be done.
942: .keywords: matrix, load, binary, input
944: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
946: @*/
947: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
948: {
950: PetscBool isbinary,flg;
955: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
956: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
958: if (!((PetscObject)newmat)->type_name) {
959: MatSetType(newmat,MATAIJ);
960: }
962: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
963: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
964: (*newmat->ops->load)(newmat,viewer);
965: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
967: flg = PETSC_FALSE;
968: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
969: if (flg) {
970: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
971: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
972: }
973: flg = PETSC_FALSE;
974: PetscOptionsGetBool(((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
975: if (flg) {
976: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
977: }
978: return(0);
979: }
983: /*@
984: MatDestroy - Frees space taken by a matrix.
986: Collective on Mat
988: Input Parameter:
989: . A - the matrix
991: Level: beginner
993: @*/
994: PetscErrorCode MatDestroy(Mat *A)
995: {
999: if (!*A) return(0);
1001: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1003: PetscViewerDestroy(&(*A)->viewonassembly);
1004: /* if memory was published with AMS then destroy it */
1005: PetscObjectAMSViewOff((PetscObject)*A);
1006: if ((*A)->ops->destroy) {
1007: (*(*A)->ops->destroy)(*A);
1008: }
1009: MatNullSpaceDestroy(&(*A)->nullsp);
1010: MatNullSpaceDestroy(&(*A)->nearnullsp);
1011: PetscLayoutDestroy(&(*A)->rmap);
1012: PetscLayoutDestroy(&(*A)->cmap);
1013: PetscHeaderDestroy(A);
1014: return(0);
1015: }
1019: /*@
1020: MatSetValues - Inserts or adds a block of values into a matrix.
1021: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1022: MUST be called after all calls to MatSetValues() have been completed.
1024: Not Collective
1026: Input Parameters:
1027: + mat - the matrix
1028: . v - a logically two-dimensional array of values
1029: . m, idxm - the number of rows and their global indices
1030: . n, idxn - the number of columns and their global indices
1031: - addv - either ADD_VALUES or INSERT_VALUES, where
1032: ADD_VALUES adds values to any existing entries, and
1033: INSERT_VALUES replaces existing entries with new values
1035: Notes:
1036: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1037: MatSetUp() before using this routine
1039: By default the values, v, are row-oriented. See MatSetOption() for other options.
1041: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1042: options cannot be mixed without intervening calls to the assembly
1043: routines.
1045: MatSetValues() uses 0-based row and column numbers in Fortran
1046: as well as in C.
1048: Negative indices may be passed in idxm and idxn, these rows and columns are
1049: simply ignored. This allows easily inserting element stiffness matrices
1050: with homogeneous Dirchlet boundary conditions that you don't want represented
1051: in the matrix.
1053: Efficiency Alert:
1054: The routine MatSetValuesBlocked() may offer much better efficiency
1055: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1057: Level: beginner
1059: Concepts: matrices^putting entries in
1061: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1062: InsertMode, INSERT_VALUES, ADD_VALUES
1063: @*/
1064: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1065: {
1067: #if defined(PETSC_USE_DEBUG)
1068: PetscInt i,j;
1069: #endif
1074: if (!m || !n) return(0); /* no values to insert */
1078: MatCheckPreallocated(mat,1);
1079: if (mat->insertmode == NOT_SET_VALUES) {
1080: mat->insertmode = addv;
1081: }
1082: #if defined(PETSC_USE_DEBUG)
1083: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1084: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1085: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1087: if (v) {
1088: for (i=0; i<m; i++) {
1089: for (j=0; j<n; j++) {
1090: if (PetscIsInfOrNanScalar(v[i*n+j]))
1091: #if defined(PETSC_USE_COMPLEX)
1092: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G+iG at matrix entry (%D,%D)",PetscRealPart(v[i*n+j]),PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1093: #else
1094: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %G at matrix entry (%D,%D)",(PetscReal)v[i*n+j],idxm[i],idxn[j]);
1095: #endif
1096: }
1097: }
1098: }
1099: #endif
1101: if (mat->assembled) {
1102: mat->was_assembled = PETSC_TRUE;
1103: mat->assembled = PETSC_FALSE;
1104: }
1105: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1106: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1107: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1108: #if defined(PETSC_HAVE_CUSP)
1109: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1110: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1111: }
1112: #endif
1113: return(0);
1114: }
1119: /*@
1120: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1121: values into a matrix
1123: Not Collective
1125: Input Parameters:
1126: + mat - the matrix
1127: . row - the (block) row to set
1128: - v - a logically two-dimensional array of values
1130: Notes:
1131: By the values, v, are column-oriented (for the block version) and sorted
1133: All the nonzeros in the row must be provided
1135: The matrix must have previously had its column indices set
1137: The row must belong to this process
1139: Level: intermediate
1141: Concepts: matrices^putting entries in
1143: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1144: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1145: @*/
1146: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1147: {
1149: PetscInt globalrow;
1155: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1156: MatSetValuesRow(mat,globalrow,v);
1157: #if defined(PETSC_HAVE_CUSP)
1158: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1159: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1160: }
1161: #endif
1162: return(0);
1163: }
1167: /*@
1168: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1169: values into a matrix
1171: Not Collective
1173: Input Parameters:
1174: + mat - the matrix
1175: . row - the (block) row to set
1176: - v - a logically two-dimensional array of values
1178: Notes:
1179: The values, v, are column-oriented for the block version.
1181: All the nonzeros in the row must be provided
1183: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1185: The row must belong to this process
1187: Level: advanced
1189: Concepts: matrices^putting entries in
1191: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1192: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1193: @*/
1194: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1195: {
1201: MatCheckPreallocated(mat,1);
1203: #if defined(PETSC_USE_DEBUG)
1204: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1205: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1206: #endif
1207: mat->insertmode = INSERT_VALUES;
1209: if (mat->assembled) {
1210: mat->was_assembled = PETSC_TRUE;
1211: mat->assembled = PETSC_FALSE;
1212: }
1213: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1214: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1215: (*mat->ops->setvaluesrow)(mat,row,v);
1216: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1217: #if defined(PETSC_HAVE_CUSP)
1218: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1219: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1220: }
1221: #endif
1222: return(0);
1223: }
1227: /*@
1228: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1229: Using structured grid indexing
1231: Not Collective
1233: Input Parameters:
1234: + mat - the matrix
1235: . m - number of rows being entered
1236: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1237: . n - number of columns being entered
1238: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1239: . v - a logically two-dimensional array of values
1240: - addv - either ADD_VALUES or INSERT_VALUES, where
1241: ADD_VALUES adds values to any existing entries, and
1242: INSERT_VALUES replaces existing entries with new values
1244: Notes:
1245: By default the values, v, are row-oriented. See MatSetOption() for other options.
1247: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1248: options cannot be mixed without intervening calls to the assembly
1249: routines.
1251: The grid coordinates are across the entire grid, not just the local portion
1253: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1254: as well as in C.
1256: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1258: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1259: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1261: The columns and rows in the stencil passed in MUST be contained within the
1262: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1263: if you create a DMDA with an overlap of one grid level and on a particular process its first
1264: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1265: first i index you can use in your column and row indices in MatSetStencil() is 5.
1267: In Fortran idxm and idxn should be declared as
1268: $ MatStencil idxm(4,m),idxn(4,n)
1269: and the values inserted using
1270: $ idxm(MatStencil_i,1) = i
1271: $ idxm(MatStencil_j,1) = j
1272: $ idxm(MatStencil_k,1) = k
1273: $ idxm(MatStencil_c,1) = c
1274: etc
1276: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1277: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1278: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1279: DMDA_BOUNDARY_PERIODIC boundary type.
1281: 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
1282: a single value per point) you can skip filling those indices.
1284: Inspired by the structured grid interface to the HYPRE package
1285: (http://www.llnl.gov/CASC/hypre)
1287: Efficiency Alert:
1288: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1289: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1291: Level: beginner
1293: Concepts: matrices^putting entries in
1295: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1296: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1297: @*/
1298: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1299: {
1301: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1302: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1303: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1306: if (!m || !n) return(0); /* no values to insert */
1313: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1314: jdxm = buf; jdxn = buf+m;
1315: } else {
1316: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1317: jdxm = bufm; jdxn = bufn;
1318: }
1319: for (i=0; i<m; i++) {
1320: for (j=0; j<3-sdim; j++) dxm++;
1321: tmp = *dxm++ - starts[0];
1322: for (j=0; j<dim-1; j++) {
1323: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1324: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1325: }
1326: if (mat->stencil.noc) dxm++;
1327: jdxm[i] = tmp;
1328: }
1329: for (i=0; i<n; i++) {
1330: for (j=0; j<3-sdim; j++) dxn++;
1331: tmp = *dxn++ - starts[0];
1332: for (j=0; j<dim-1; j++) {
1333: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1334: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1335: }
1336: if (mat->stencil.noc) dxn++;
1337: jdxn[i] = tmp;
1338: }
1339: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1340: PetscFree2(bufm,bufn);
1341: return(0);
1342: }
1346: /*@
1347: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1348: Using structured grid indexing
1350: Not Collective
1352: Input Parameters:
1353: + mat - the matrix
1354: . m - number of rows being entered
1355: . idxm - grid coordinates for matrix rows being entered
1356: . n - number of columns being entered
1357: . idxn - grid coordinates for matrix columns being entered
1358: . v - a logically two-dimensional array of values
1359: - addv - either ADD_VALUES or INSERT_VALUES, where
1360: ADD_VALUES adds values to any existing entries, and
1361: INSERT_VALUES replaces existing entries with new values
1363: Notes:
1364: By default the values, v, are row-oriented and unsorted.
1365: See MatSetOption() for other options.
1367: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1368: options cannot be mixed without intervening calls to the assembly
1369: routines.
1371: The grid coordinates are across the entire grid, not just the local portion
1373: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1374: as well as in C.
1376: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1378: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1379: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1381: The columns and rows in the stencil passed in MUST be contained within the
1382: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1383: if you create a DMDA with an overlap of one grid level and on a particular process its first
1384: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1385: first i index you can use in your column and row indices in MatSetStencil() is 5.
1387: In Fortran idxm and idxn should be declared as
1388: $ MatStencil idxm(4,m),idxn(4,n)
1389: and the values inserted using
1390: $ idxm(MatStencil_i,1) = i
1391: $ idxm(MatStencil_j,1) = j
1392: $ idxm(MatStencil_k,1) = k
1393: etc
1395: Negative indices may be passed in idxm and idxn, these rows and columns are
1396: simply ignored. This allows easily inserting element stiffness matrices
1397: with homogeneous Dirchlet boundary conditions that you don't want represented
1398: in the matrix.
1400: Inspired by the structured grid interface to the HYPRE package
1401: (http://www.llnl.gov/CASC/hypre)
1403: Level: beginner
1405: Concepts: matrices^putting entries in
1407: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1408: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1409: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1410: @*/
1411: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1412: {
1414: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1415: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1416: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1419: if (!m || !n) return(0); /* no values to insert */
1426: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1427: jdxm = buf; jdxn = buf+m;
1428: } else {
1429: PetscMalloc2(m,PetscInt,&bufm,n,PetscInt,&bufn);
1430: jdxm = bufm; jdxn = bufn;
1431: }
1432: for (i=0; i<m; i++) {
1433: for (j=0; j<3-sdim; j++) dxm++;
1434: tmp = *dxm++ - starts[0];
1435: for (j=0; j<sdim-1; j++) {
1436: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1437: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1438: }
1439: dxm++;
1440: jdxm[i] = tmp;
1441: }
1442: for (i=0; i<n; i++) {
1443: for (j=0; j<3-sdim; j++) dxn++;
1444: tmp = *dxn++ - starts[0];
1445: for (j=0; j<sdim-1; j++) {
1446: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1447: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1448: }
1449: dxn++;
1450: jdxn[i] = tmp;
1451: }
1452: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1453: PetscFree2(bufm,bufn);
1454: #if defined(PETSC_HAVE_CUSP)
1455: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1456: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1457: }
1458: #endif
1459: return(0);
1460: }
1464: /*@
1465: MatSetStencil - Sets the grid information for setting values into a matrix via
1466: MatSetValuesStencil()
1468: Not Collective
1470: Input Parameters:
1471: + mat - the matrix
1472: . dim - dimension of the grid 1, 2, or 3
1473: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1474: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1475: - dof - number of degrees of freedom per node
1478: Inspired by the structured grid interface to the HYPRE package
1479: (www.llnl.gov/CASC/hyper)
1481: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1482: user.
1484: Level: beginner
1486: Concepts: matrices^putting entries in
1488: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1489: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1490: @*/
1491: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1492: {
1493: PetscInt i;
1500: mat->stencil.dim = dim + (dof > 1);
1501: for (i=0; i<dim; i++) {
1502: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1503: mat->stencil.starts[i] = starts[dim-i-1];
1504: }
1505: mat->stencil.dims[dim] = dof;
1506: mat->stencil.starts[dim] = 0;
1507: mat->stencil.noc = (PetscBool)(dof == 1);
1508: return(0);
1509: }
1513: /*@
1514: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1516: Not Collective
1518: Input Parameters:
1519: + mat - the matrix
1520: . v - a logically two-dimensional array of values
1521: . m, idxm - the number of block rows and their global block indices
1522: . n, idxn - the number of block columns and their global block indices
1523: - addv - either ADD_VALUES or INSERT_VALUES, where
1524: ADD_VALUES adds values to any existing entries, and
1525: INSERT_VALUES replaces existing entries with new values
1527: Notes:
1528: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1529: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1531: The m and n count the NUMBER of blocks in the row direction and column direction,
1532: NOT the total number of rows/columns; for example, if the block size is 2 and
1533: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1534: The values in idxm would be 1 2; that is the first index for each block divided by
1535: the block size.
1537: Note that you must call MatSetBlockSize() when constructing this matrix (after
1538: preallocating it).
1540: By default the values, v, are row-oriented, so the layout of
1541: v is the same as for MatSetValues(). See MatSetOption() for other options.
1543: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1544: options cannot be mixed without intervening calls to the assembly
1545: routines.
1547: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1548: as well as in C.
1550: Negative indices may be passed in idxm and idxn, these rows and columns are
1551: simply ignored. This allows easily inserting element stiffness matrices
1552: with homogeneous Dirchlet boundary conditions that you don't want represented
1553: in the matrix.
1555: Each time an entry is set within a sparse matrix via MatSetValues(),
1556: internal searching must be done to determine where to place the the
1557: data in the matrix storage space. By instead inserting blocks of
1558: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1559: reduced.
1561: Example:
1562: $ Suppose m=n=2 and block size(bs) = 2 The array is
1563: $
1564: $ 1 2 | 3 4
1565: $ 5 6 | 7 8
1566: $ - - - | - - -
1567: $ 9 10 | 11 12
1568: $ 13 14 | 15 16
1569: $
1570: $ v[] should be passed in like
1571: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1572: $
1573: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1574: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1576: Level: intermediate
1578: Concepts: matrices^putting entries in blocked
1580: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1581: @*/
1582: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1583: {
1589: if (!m || !n) return(0); /* no values to insert */
1593: MatCheckPreallocated(mat,1);
1594: if (mat->insertmode == NOT_SET_VALUES) {
1595: mat->insertmode = addv;
1596: }
1597: #if defined(PETSC_USE_DEBUG)
1598: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1599: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1600: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1601: #endif
1603: if (mat->assembled) {
1604: mat->was_assembled = PETSC_TRUE;
1605: mat->assembled = PETSC_FALSE;
1606: }
1607: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1608: if (mat->ops->setvaluesblocked) {
1609: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1610: } else {
1611: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1612: PetscInt i,j,bs = mat->rmap->bs,cbs = mat->cmap->bs;
1613: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1614: iidxm = buf; iidxn = buf + m*bs;
1615: } else {
1616: PetscMalloc2(m*bs,PetscInt,&bufr,n*cbs,PetscInt,&bufc);
1617: iidxm = bufr; iidxn = bufc;
1618: }
1619: for (i=0; i<m; i++) {
1620: for (j=0; j<bs; j++) {
1621: iidxm[i*bs+j] = bs*idxm[i] + j;
1622: }
1623: }
1624: for (i=0; i<n; i++) {
1625: for (j=0; j<cbs; j++) {
1626: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1627: }
1628: }
1629: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1630: PetscFree2(bufr,bufc);
1631: }
1632: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1633: #if defined(PETSC_HAVE_CUSP)
1634: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1635: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1636: }
1637: #endif
1638: return(0);
1639: }
1643: /*@
1644: MatGetValues - Gets a block of values from a matrix.
1646: Not Collective; currently only returns a local block
1648: Input Parameters:
1649: + mat - the matrix
1650: . v - a logically two-dimensional array for storing the values
1651: . m, idxm - the number of rows and their global indices
1652: - n, idxn - the number of columns and their global indices
1654: Notes:
1655: The user must allocate space (m*n PetscScalars) for the values, v.
1656: The values, v, are then returned in a row-oriented format,
1657: analogous to that used by default in MatSetValues().
1659: MatGetValues() uses 0-based row and column numbers in
1660: Fortran as well as in C.
1662: MatGetValues() requires that the matrix has been assembled
1663: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1664: MatSetValues() and MatGetValues() CANNOT be made in succession
1665: without intermediate matrix assembly.
1667: Negative row or column indices will be ignored and those locations in v[] will be
1668: left unchanged.
1670: Level: advanced
1672: Concepts: matrices^accessing values
1674: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1675: @*/
1676: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1677: {
1683: if (!m || !n) return(0);
1687: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1688: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1689: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1690: MatCheckPreallocated(mat,1);
1692: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1693: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1694: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1695: return(0);
1696: }
1700: /*@
1701: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1702: the same size. Currently, this can only be called once and creates the given matrix.
1704: Not Collective
1706: Input Parameters:
1707: + mat - the matrix
1708: . nb - the number of blocks
1709: . bs - the number of rows (and columns) in each block
1710: . rows - a concatenation of the rows for each block
1711: - v - a concatenation of logically two-dimensional arrays of values
1713: Notes:
1714: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1716: Level: advanced
1718: Concepts: matrices^putting entries in
1720: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1721: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1722: @*/
1723: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1724: {
1732: #if defined(PETSC_USE_DEBUG)
1733: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1734: #endif
1736: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1737: if (mat->ops->setvaluesbatch) {
1738: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1739: } else {
1740: PetscInt b;
1741: for (b = 0; b < nb; ++b) {
1742: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1743: }
1744: }
1745: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1746: return(0);
1747: }
1751: /*@
1752: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1753: the routine MatSetValuesLocal() to allow users to insert matrix entries
1754: using a local (per-processor) numbering.
1756: Not Collective
1758: Input Parameters:
1759: + x - the matrix
1760: . rmapping - row mapping created with ISLocalToGlobalMappingCreate()
1761: or ISLocalToGlobalMappingCreateIS()
1762: - cmapping - column mapping
1764: Level: intermediate
1766: Concepts: matrices^local to global mapping
1767: Concepts: local to global mapping^for matrices
1769: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1770: @*/
1771: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1772: {
1781: if (x->ops->setlocaltoglobalmapping) {
1782: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1783: } else {
1784: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1785: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1786: }
1787: return(0);
1788: }
1792: /*@
1793: MatSetLocalToGlobalMappingBlock - Sets a local-to-global numbering for use
1794: by the routine MatSetValuesBlockedLocal() to allow users to insert matrix
1795: entries using a local (per-processor) numbering.
1797: Not Collective
1799: Input Parameters:
1800: + x - the matrix
1801: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or
1802: ISLocalToGlobalMappingCreateIS()
1803: - cmapping - column mapping
1805: Level: intermediate
1807: Concepts: matrices^local to global mapping blocked
1808: Concepts: local to global mapping^for matrices, blocked
1810: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal(),
1811: MatSetValuesBlocked(), MatSetValuesLocal()
1812: @*/
1813: PetscErrorCode MatSetLocalToGlobalMappingBlock(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1814: {
1823: PetscLayoutSetISLocalToGlobalMappingBlock(x->rmap,rmapping);
1824: PetscLayoutSetISLocalToGlobalMappingBlock(x->cmap,cmapping);
1825: return(0);
1826: }
1830: /*@
1831: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1833: Not Collective
1835: Input Parameters:
1836: . A - the matrix
1838: Output Parameters:
1839: + rmapping - row mapping
1840: - cmapping - column mapping
1842: Level: advanced
1844: Concepts: matrices^local to global mapping
1845: Concepts: local to global mapping^for matrices
1847: .seealso: MatSetValuesLocal(), MatGetLocalToGlobalMappingBlock()
1848: @*/
1849: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1850: {
1856: if (rmapping) *rmapping = A->rmap->mapping;
1857: if (cmapping) *cmapping = A->cmap->mapping;
1858: return(0);
1859: }
1863: /*@
1864: MatGetLocalToGlobalMappingBlock - Gets the local-to-global numbering set by MatSetLocalToGlobalMappingBlock()
1866: Not Collective
1868: Input Parameters:
1869: . A - the matrix
1871: Output Parameters:
1872: + rmapping - row mapping
1873: - cmapping - column mapping
1875: Level: advanced
1877: Concepts: matrices^local to global mapping blocked
1878: Concepts: local to global mapping^for matrices, blocked
1880: .seealso: MatSetValuesBlockedLocal(), MatGetLocalToGlobalMapping()
1881: @*/
1882: PetscErrorCode MatGetLocalToGlobalMappingBlock(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1883: {
1889: if (rmapping) *rmapping = A->rmap->bmapping;
1890: if (cmapping) *cmapping = A->cmap->bmapping;
1891: return(0);
1892: }
1896: /*@
1897: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1898: using a local ordering of the nodes.
1900: Not Collective
1902: Input Parameters:
1903: + x - the matrix
1904: . nrow, irow - number of rows and their local indices
1905: . ncol, icol - number of columns and their local indices
1906: . y - a logically two-dimensional array of values
1907: - addv - either INSERT_VALUES or ADD_VALUES, where
1908: ADD_VALUES adds values to any existing entries, and
1909: INSERT_VALUES replaces existing entries with new values
1911: Notes:
1912: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1913: MatSetUp() before using this routine
1915: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
1917: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
1918: options cannot be mixed without intervening calls to the assembly
1919: routines.
1921: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1922: MUST be called after all calls to MatSetValuesLocal() have been completed.
1924: Level: intermediate
1926: Concepts: matrices^putting entries in with local numbering
1928: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
1929: MatSetValueLocal()
1930: @*/
1931: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
1932: {
1938: MatCheckPreallocated(mat,1);
1939: if (!nrow || !ncol) return(0); /* no values to insert */
1943: if (mat->insertmode == NOT_SET_VALUES) {
1944: mat->insertmode = addv;
1945: }
1946: #if defined(PETSC_USE_DEBUG)
1947: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1948: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1949: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1950: #endif
1952: if (mat->assembled) {
1953: mat->was_assembled = PETSC_TRUE;
1954: mat->assembled = PETSC_FALSE;
1955: }
1956: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1957: if (mat->ops->setvalueslocal) {
1958: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
1959: } else {
1960: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
1961: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1962: irowm = buf; icolm = buf+nrow;
1963: } else {
1964: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
1965: irowm = bufr; icolm = bufc;
1966: }
1967: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
1968: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
1969: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
1970: PetscFree2(bufr,bufc);
1971: }
1972: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1973: #if defined(PETSC_HAVE_CUSP)
1974: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1975: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1976: }
1977: #endif
1978: return(0);
1979: }
1983: /*@
1984: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
1985: using a local ordering of the nodes a block at a time.
1987: Not Collective
1989: Input Parameters:
1990: + x - the matrix
1991: . nrow, irow - number of rows and their local indices
1992: . ncol, icol - number of columns and their local indices
1993: . y - a logically two-dimensional array of values
1994: - addv - either INSERT_VALUES or ADD_VALUES, where
1995: ADD_VALUES adds values to any existing entries, and
1996: INSERT_VALUES replaces existing entries with new values
1998: Notes:
1999: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2000: MatSetUp() before using this routine
2002: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMappingBlock()
2003: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2005: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2006: options cannot be mixed without intervening calls to the assembly
2007: routines.
2009: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2010: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2012: Level: intermediate
2014: Concepts: matrices^putting blocked values in with local numbering
2016: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMappingBlock(), MatAssemblyBegin(), MatAssemblyEnd(),
2017: MatSetValuesLocal(), MatSetLocalToGlobalMappingBlock(), MatSetValuesBlocked()
2018: @*/
2019: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2020: {
2026: MatCheckPreallocated(mat,1);
2027: if (!nrow || !ncol) return(0); /* no values to insert */
2031: if (mat->insertmode == NOT_SET_VALUES) {
2032: mat->insertmode = addv;
2033: }
2034: #if defined(PETSC_USE_DEBUG)
2035: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2036: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2037: 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);
2038: #endif
2040: if (mat->assembled) {
2041: mat->was_assembled = PETSC_TRUE;
2042: mat->assembled = PETSC_FALSE;
2043: }
2044: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2045: if (mat->ops->setvaluesblockedlocal) {
2046: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2047: } else {
2048: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2049: if (mat->rmap->bmapping && mat->cmap->bmapping) {
2050: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2051: irowm = buf; icolm = buf + nrow;
2052: } else {
2053: PetscMalloc2(nrow,PetscInt,&bufr,ncol,PetscInt,&bufc);
2054: irowm = bufr; icolm = bufc;
2055: }
2056: ISLocalToGlobalMappingApply(mat->rmap->bmapping,nrow,irow,irowm);
2057: ISLocalToGlobalMappingApply(mat->cmap->bmapping,ncol,icol,icolm);
2058: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2059: PetscFree2(bufr,bufc);
2060: } else {
2061: PetscInt i,j,bs = mat->rmap->bs,cbs = mat->cmap->bs;
2062: if (nrow*bs+ncol*cbs <=(PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2063: irowm = buf; icolm = buf + nrow;
2064: } else {
2065: PetscMalloc2(nrow*bs,PetscInt,&bufr,ncol*cbs,PetscInt,&bufc);
2066: irowm = bufr; icolm = bufc;
2067: }
2068: for (i=0; i<nrow; i++) {
2069: for (j=0; j<bs; j++) irowm[i*bs+j] = irow[i]*bs+j;
2070: }
2071: for (i=0; i<ncol; i++) {
2072: for (j=0; j<cbs; j++) icolm[i*cbs+j] = icol[i]*cbs+j;
2073: }
2074: MatSetValuesLocal(mat,nrow*bs,irowm,ncol*cbs,icolm,y,addv);
2075: PetscFree2(bufr,bufc);
2076: }
2077: }
2078: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2079: #if defined(PETSC_HAVE_CUSP)
2080: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2081: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2082: }
2083: #endif
2084: return(0);
2085: }
2089: /*@
2090: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2092: Collective on Mat and Vec
2094: Input Parameters:
2095: + mat - the matrix
2096: - x - the vector to be multiplied
2098: Output Parameters:
2099: . y - the result
2101: Notes:
2102: The vectors x and y cannot be the same. I.e., one cannot
2103: call MatMult(A,y,y).
2105: Level: developer
2107: Concepts: matrix-vector product
2109: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2110: @*/
2111: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2112: {
2121: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2122: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2123: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2124: MatCheckPreallocated(mat,1);
2126: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2127: (*mat->ops->multdiagonalblock)(mat,x,y);
2128: PetscObjectStateIncrease((PetscObject)y);
2129: return(0);
2130: }
2132: /* --------------------------------------------------------*/
2135: /*@
2136: MatMult - Computes the matrix-vector product, y = Ax.
2138: Neighbor-wise Collective on Mat and Vec
2140: Input Parameters:
2141: + mat - the matrix
2142: - x - the vector to be multiplied
2144: Output Parameters:
2145: . y - the result
2147: Notes:
2148: The vectors x and y cannot be the same. I.e., one cannot
2149: call MatMult(A,y,y).
2151: Level: beginner
2153: Concepts: matrix-vector product
2155: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2156: @*/
2157: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2158: {
2166: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2167: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2168: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2169: #if !defined(PETSC_HAVE_CONSTRAINTS)
2170: 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);
2171: 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);
2172: 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);
2173: #endif
2174: VecValidValues(x,2,PETSC_TRUE);
2175: MatCheckPreallocated(mat,1);
2177: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2178: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2179: (*mat->ops->mult)(mat,x,y);
2180: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2181: VecValidValues(y,3,PETSC_FALSE);
2182: return(0);
2183: }
2187: /*@
2188: MatMultTranspose - Computes matrix transpose times a vector.
2190: Neighbor-wise Collective on Mat and Vec
2192: Input Parameters:
2193: + mat - the matrix
2194: - x - the vector to be multilplied
2196: Output Parameters:
2197: . y - the result
2199: Notes:
2200: The vectors x and y cannot be the same. I.e., one cannot
2201: call MatMultTranspose(A,y,y).
2203: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2204: use MatMultHermitianTranspose()
2206: Level: beginner
2208: Concepts: matrix vector product^transpose
2210: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2211: @*/
2212: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2213: {
2222: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2223: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2224: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2225: #if !defined(PETSC_HAVE_CONSTRAINTS)
2226: 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);
2227: 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);
2228: #endif
2229: VecValidValues(x,2,PETSC_TRUE);
2230: MatCheckPreallocated(mat,1);
2232: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2233: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2234: (*mat->ops->multtranspose)(mat,x,y);
2235: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2236: PetscObjectStateIncrease((PetscObject)y);
2237: VecValidValues(y,3,PETSC_FALSE);
2238: return(0);
2239: }
2243: /*@
2244: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2246: Neighbor-wise Collective on Mat and Vec
2248: Input Parameters:
2249: + mat - the matrix
2250: - x - the vector to be multilplied
2252: Output Parameters:
2253: . y - the result
2255: Notes:
2256: The vectors x and y cannot be the same. I.e., one cannot
2257: call MatMultHermitianTranspose(A,y,y).
2259: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2261: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2263: Level: beginner
2265: Concepts: matrix vector product^transpose
2267: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2268: @*/
2269: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2270: {
2272: Vec w;
2280: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2281: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2282: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2283: #if !defined(PETSC_HAVE_CONSTRAINTS)
2284: if (mat->rmap->N != x->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec x: global dim %D %D",mat->rmap->N,x->map->N);
2285: if (mat->cmap->N != y->map->N) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec y: global dim %D %D",mat->cmap->N,y->map->N);
2286: #endif
2287: MatCheckPreallocated(mat,1);
2289: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2290: if (mat->ops->multhermitiantranspose) {
2291: (*mat->ops->multhermitiantranspose)(mat,x,y);
2292: } else {
2293: VecDuplicate(x,&w);
2294: VecCopy(x,w);
2295: VecConjugate(w);
2296: MatMultTranspose(mat,w,y);
2297: VecDestroy(&w);
2298: VecConjugate(y);
2299: }
2300: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2301: PetscObjectStateIncrease((PetscObject)y);
2302: return(0);
2303: }
2307: /*@
2308: MatMultAdd - Computes v3 = v2 + A * v1.
2310: Neighbor-wise Collective on Mat and Vec
2312: Input Parameters:
2313: + mat - the matrix
2314: - v1, v2 - the vectors
2316: Output Parameters:
2317: . v3 - the result
2319: Notes:
2320: The vectors v1 and v3 cannot be the same. I.e., one cannot
2321: call MatMultAdd(A,v1,v2,v1).
2323: Level: beginner
2325: Concepts: matrix vector product^addition
2327: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2328: @*/
2329: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2330: {
2340: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2341: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2342: 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);
2343: /* 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);
2344: 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); */
2345: 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);
2346: 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);
2347: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2348: MatCheckPreallocated(mat,1);
2350: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2351: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2352: (*mat->ops->multadd)(mat,v1,v2,v3);
2353: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2354: PetscObjectStateIncrease((PetscObject)v3);
2355: return(0);
2356: }
2360: /*@
2361: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2363: Neighbor-wise Collective on Mat and Vec
2365: Input Parameters:
2366: + mat - the matrix
2367: - v1, v2 - the vectors
2369: Output Parameters:
2370: . v3 - the result
2372: Notes:
2373: The vectors v1 and v3 cannot be the same. I.e., one cannot
2374: call MatMultTransposeAdd(A,v1,v2,v1).
2376: Level: beginner
2378: Concepts: matrix vector product^transpose and addition
2380: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2381: @*/
2382: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2383: {
2393: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2394: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2395: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2396: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2397: 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);
2398: 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);
2399: 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);
2400: MatCheckPreallocated(mat,1);
2402: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2403: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2404: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2405: PetscObjectStateIncrease((PetscObject)v3);
2406: return(0);
2407: }
2411: /*@
2412: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2414: Neighbor-wise Collective on Mat and Vec
2416: Input Parameters:
2417: + mat - the matrix
2418: - v1, v2 - the vectors
2420: Output Parameters:
2421: . v3 - the result
2423: Notes:
2424: The vectors v1 and v3 cannot be the same. I.e., one cannot
2425: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2427: Level: beginner
2429: Concepts: matrix vector product^transpose and addition
2431: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2432: @*/
2433: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2434: {
2444: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2445: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2446: if (!mat->ops->multhermitiantransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2447: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2448: 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);
2449: 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);
2450: 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);
2451: MatCheckPreallocated(mat,1);
2453: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2454: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2455: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2456: PetscObjectStateIncrease((PetscObject)v3);
2457: return(0);
2458: }
2462: /*@
2463: MatMultConstrained - The inner multiplication routine for a
2464: constrained matrix P^T A P.
2466: Neighbor-wise Collective on Mat and Vec
2468: Input Parameters:
2469: + mat - the matrix
2470: - x - the vector to be multilplied
2472: Output Parameters:
2473: . y - the result
2475: Notes:
2476: The vectors x and y cannot be the same. I.e., one cannot
2477: call MatMult(A,y,y).
2479: Level: beginner
2481: .keywords: matrix, multiply, matrix-vector product, constraint
2482: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2483: @*/
2484: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2485: {
2492: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2493: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2494: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2495: 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);
2496: 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);
2497: 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);
2499: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2500: (*mat->ops->multconstrained)(mat,x,y);
2501: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2502: PetscObjectStateIncrease((PetscObject)y);
2503: return(0);
2504: }
2508: /*@
2509: MatMultTransposeConstrained - The inner multiplication routine for a
2510: constrained matrix P^T A^T P.
2512: Neighbor-wise Collective on Mat and Vec
2514: Input Parameters:
2515: + mat - the matrix
2516: - x - the vector to be multilplied
2518: Output Parameters:
2519: . y - the result
2521: Notes:
2522: The vectors x and y cannot be the same. I.e., one cannot
2523: call MatMult(A,y,y).
2525: Level: beginner
2527: .keywords: matrix, multiply, matrix-vector product, constraint
2528: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2529: @*/
2530: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2531: {
2538: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2539: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2540: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2541: 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);
2542: 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);
2544: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2545: (*mat->ops->multtransposeconstrained)(mat,x,y);
2546: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2547: PetscObjectStateIncrease((PetscObject)y);
2548: return(0);
2549: }
2553: /*@C
2554: MatGetFactorType - gets the type of factorization it is
2556: Note Collective
2557: as the flag
2559: Input Parameters:
2560: . mat - the matrix
2562: Output Parameters:
2563: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2565: Level: intermediate
2567: .seealso: MatFactorType, MatGetFactor()
2568: @*/
2569: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2570: {
2574: *t = mat->factortype;
2575: return(0);
2576: }
2578: /* ------------------------------------------------------------*/
2581: /*@C
2582: MatGetInfo - Returns information about matrix storage (number of
2583: nonzeros, memory, etc.).
2585: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2587: Input Parameters:
2588: . mat - the matrix
2590: Output Parameters:
2591: + flag - flag indicating the type of parameters to be returned
2592: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2593: MAT_GLOBAL_SUM - sum over all processors)
2594: - info - matrix information context
2596: Notes:
2597: The MatInfo context contains a variety of matrix data, including
2598: number of nonzeros allocated and used, number of mallocs during
2599: matrix assembly, etc. Additional information for factored matrices
2600: is provided (such as the fill ratio, number of mallocs during
2601: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2602: when using the runtime options
2603: $ -info -mat_view ::ascii_info
2605: Example for C/C++ Users:
2606: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2607: data within the MatInfo context. For example,
2608: .vb
2609: MatInfo info;
2610: Mat A;
2611: double mal, nz_a, nz_u;
2613: MatGetInfo(A,MAT_LOCAL,&info);
2614: mal = info.mallocs;
2615: nz_a = info.nz_allocated;
2616: .ve
2618: Example for Fortran Users:
2619: Fortran users should declare info as a double precision
2620: array of dimension MAT_INFO_SIZE, and then extract the parameters
2621: of interest. See the file ${PETSC_DIR}/include/finclude/petscmat.h
2622: a complete list of parameter names.
2623: .vb
2624: double precision info(MAT_INFO_SIZE)
2625: double precision mal, nz_a
2626: Mat A
2627: integer ierr
2629: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2630: mal = info(MAT_INFO_MALLOCS)
2631: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2632: .ve
2634: Level: intermediate
2636: Concepts: matrices^getting information on
2638: Developer Note: fortran interface is not autogenerated as the f90
2639: interface defintion cannot be generated correctly [due to MatInfo]
2641: .seealso: MatStashGetInfo()
2643: @*/
2644: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2645: {
2652: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2653: MatCheckPreallocated(mat,1);
2654: (*mat->ops->getinfo)(mat,flag,info);
2655: return(0);
2656: }
2658: /* ----------------------------------------------------------*/
2662: /*@C
2663: MatLUFactor - Performs in-place LU factorization of matrix.
2665: Collective on Mat
2667: Input Parameters:
2668: + mat - the matrix
2669: . row - row permutation
2670: . col - column permutation
2671: - info - options for factorization, includes
2672: $ fill - expected fill as ratio of original fill.
2673: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2674: $ Run with the option -info to determine an optimal value to use
2676: Notes:
2677: Most users should employ the simplified KSP interface for linear solvers
2678: instead of working directly with matrix algebra routines such as this.
2679: See, e.g., KSPCreate().
2681: This changes the state of the matrix to a factored matrix; it cannot be used
2682: for example with MatSetValues() unless one first calls MatSetUnfactored().
2684: Level: developer
2686: Concepts: matrices^LU factorization
2688: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2689: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2691: Developer Note: fortran interface is not autogenerated as the f90
2692: interface defintion cannot be generated correctly [due to MatFactorInfo]
2694: @*/
2695: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2696: {
2698: MatFactorInfo tinfo;
2706: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2707: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2708: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2709: MatCheckPreallocated(mat,1);
2710: if (!info) {
2711: MatFactorInfoInitialize(&tinfo);
2712: info = &tinfo;
2713: }
2715: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2716: (*mat->ops->lufactor)(mat,row,col,info);
2717: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2718: PetscObjectStateIncrease((PetscObject)mat);
2719: return(0);
2720: }
2724: /*@C
2725: MatILUFactor - Performs in-place ILU factorization of matrix.
2727: Collective on Mat
2729: Input Parameters:
2730: + mat - the matrix
2731: . row - row permutation
2732: . col - column permutation
2733: - info - structure containing
2734: $ levels - number of levels of fill.
2735: $ expected fill - as ratio of original fill.
2736: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2737: missing diagonal entries)
2739: Notes:
2740: Probably really in-place only when level of fill is zero, otherwise allocates
2741: new space to store factored matrix and deletes previous memory.
2743: Most users should employ the simplified KSP interface for linear solvers
2744: instead of working directly with matrix algebra routines such as this.
2745: See, e.g., KSPCreate().
2747: Level: developer
2749: Concepts: matrices^ILU factorization
2751: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2753: Developer Note: fortran interface is not autogenerated as the f90
2754: interface defintion cannot be generated correctly [due to MatFactorInfo]
2756: @*/
2757: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2758: {
2767: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2768: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2769: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2770: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2771: MatCheckPreallocated(mat,1);
2773: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2774: (*mat->ops->ilufactor)(mat,row,col,info);
2775: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2776: PetscObjectStateIncrease((PetscObject)mat);
2777: return(0);
2778: }
2782: /*@C
2783: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2784: Call this routine before calling MatLUFactorNumeric().
2786: Collective on Mat
2788: Input Parameters:
2789: + fact - the factor matrix obtained with MatGetFactor()
2790: . mat - the matrix
2791: . row, col - row and column permutations
2792: - info - options for factorization, includes
2793: $ fill - expected fill as ratio of original fill.
2794: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2795: $ Run with the option -info to determine an optimal value to use
2798: Notes:
2799: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
2800: choosing the fill factor for better efficiency.
2802: Most users should employ the simplified KSP interface for linear solvers
2803: instead of working directly with matrix algebra routines such as this.
2804: See, e.g., KSPCreate().
2806: Level: developer
2808: Concepts: matrices^LU symbolic factorization
2810: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2812: Developer Note: fortran interface is not autogenerated as the f90
2813: interface defintion cannot be generated correctly [due to MatFactorInfo]
2815: @*/
2816: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2817: {
2827: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2828: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2829: if (!(fact)->ops->lufactorsymbolic) {
2830: const MatSolverPackage spackage;
2831: MatFactorGetSolverPackage(fact,&spackage);
2832: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2833: }
2834: MatCheckPreallocated(mat,2);
2836: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2837: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2838: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2839: PetscObjectStateIncrease((PetscObject)fact);
2840: return(0);
2841: }
2845: /*@C
2846: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2847: Call this routine after first calling MatLUFactorSymbolic().
2849: Collective on Mat
2851: Input Parameters:
2852: + fact - the factor matrix obtained with MatGetFactor()
2853: . mat - the matrix
2854: - info - options for factorization
2856: Notes:
2857: See MatLUFactor() for in-place factorization. See
2858: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2860: Most users should employ the simplified KSP interface for linear solvers
2861: instead of working directly with matrix algebra routines such as this.
2862: See, e.g., KSPCreate().
2864: Level: developer
2866: Concepts: matrices^LU numeric factorization
2868: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2870: Developer Note: fortran interface is not autogenerated as the f90
2871: interface defintion cannot be generated correctly [due to MatFactorInfo]
2873: @*/
2874: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2875: {
2883: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2884: 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);
2886: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2887: MatCheckPreallocated(mat,2);
2888: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2889: (fact->ops->lufactornumeric)(fact,mat,info);
2890: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2892: if (fact->viewonassembly) {
2893: PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
2894: MatView(fact,fact->viewonassembly);
2895: PetscViewerPopFormat(fact->viewonassembly);
2896: }
2897: PetscObjectStateIncrease((PetscObject)fact);
2898: return(0);
2899: }
2903: /*@C
2904: MatCholeskyFactor - Performs in-place Cholesky factorization of a
2905: symmetric matrix.
2907: Collective on Mat
2909: Input Parameters:
2910: + mat - the matrix
2911: . perm - row and column permutations
2912: - f - expected fill as ratio of original fill
2914: Notes:
2915: See MatLUFactor() for the nonsymmetric case. See also
2916: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
2918: Most users should employ the simplified KSP interface for linear solvers
2919: instead of working directly with matrix algebra routines such as this.
2920: See, e.g., KSPCreate().
2922: Level: developer
2924: Concepts: matrices^Cholesky factorization
2926: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
2927: MatGetOrdering()
2929: Developer Note: fortran interface is not autogenerated as the f90
2930: interface defintion cannot be generated correctly [due to MatFactorInfo]
2932: @*/
2933: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
2934: {
2942: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
2943: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2944: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2945: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2946: MatCheckPreallocated(mat,1);
2948: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
2949: (*mat->ops->choleskyfactor)(mat,perm,info);
2950: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
2951: PetscObjectStateIncrease((PetscObject)mat);
2952: return(0);
2953: }
2957: /*@C
2958: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
2959: of a symmetric matrix.
2961: Collective on Mat
2963: Input Parameters:
2964: + fact - the factor matrix obtained with MatGetFactor()
2965: . mat - the matrix
2966: . perm - row and column permutations
2967: - info - options for factorization, includes
2968: $ fill - expected fill as ratio of original fill.
2969: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2970: $ Run with the option -info to determine an optimal value to use
2972: Notes:
2973: See MatLUFactorSymbolic() for the nonsymmetric case. See also
2974: MatCholeskyFactor() and MatCholeskyFactorNumeric().
2976: Most users should employ the simplified KSP interface for linear solvers
2977: instead of working directly with matrix algebra routines such as this.
2978: See, e.g., KSPCreate().
2980: Level: developer
2982: Concepts: matrices^Cholesky symbolic factorization
2984: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
2985: MatGetOrdering()
2987: Developer Note: fortran interface is not autogenerated as the f90
2988: interface defintion cannot be generated correctly [due to MatFactorInfo]
2990: @*/
2991: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
2992: {
3001: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3002: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3003: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3004: if (!(fact)->ops->choleskyfactorsymbolic) {
3005: const MatSolverPackage spackage;
3006: MatFactorGetSolverPackage(fact,&spackage);
3007: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3008: }
3009: MatCheckPreallocated(mat,2);
3011: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3012: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3013: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3014: PetscObjectStateIncrease((PetscObject)fact);
3015: return(0);
3016: }
3020: /*@C
3021: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3022: of a symmetric matrix. Call this routine after first calling
3023: MatCholeskyFactorSymbolic().
3025: Collective on Mat
3027: Input Parameters:
3028: + fact - the factor matrix obtained with MatGetFactor()
3029: . mat - the initial matrix
3030: . info - options for factorization
3031: - fact - the symbolic factor of mat
3034: Notes:
3035: Most users should employ the simplified KSP interface for linear solvers
3036: instead of working directly with matrix algebra routines such as this.
3037: See, e.g., KSPCreate().
3039: Level: developer
3041: Concepts: matrices^Cholesky numeric factorization
3043: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3045: Developer Note: fortran interface is not autogenerated as the f90
3046: interface defintion cannot be generated correctly [due to MatFactorInfo]
3048: @*/
3049: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3050: {
3058: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3059: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3060: 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);
3061: MatCheckPreallocated(mat,2);
3063: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3064: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3065: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3067: if (fact->viewonassembly) {
3068: PetscViewerPushFormat(fact->viewonassembly,fact->viewformatonassembly);
3069: MatView(fact,fact->viewonassembly);
3070: PetscViewerPopFormat(fact->viewonassembly);
3071: }
3072: PetscObjectStateIncrease((PetscObject)fact);
3073: return(0);
3074: }
3076: /* ----------------------------------------------------------------*/
3079: /*@
3080: MatSolve - Solves A x = b, given a factored matrix.
3082: Neighbor-wise Collective on Mat and Vec
3084: Input Parameters:
3085: + mat - the factored matrix
3086: - b - the right-hand-side vector
3088: Output Parameter:
3089: . x - the result vector
3091: Notes:
3092: The vectors b and x cannot be the same. I.e., one cannot
3093: call MatSolve(A,x,x).
3095: Notes:
3096: Most users should employ the simplified KSP interface for linear solvers
3097: instead of working directly with matrix algebra routines such as this.
3098: See, e.g., KSPCreate().
3100: Level: developer
3102: Concepts: matrices^triangular solves
3104: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3105: @*/
3106: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3107: {
3117: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3118: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3119: 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);
3120: 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);
3121: 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);
3122: if (!mat->rmap->N && !mat->cmap->N) return(0);
3123: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3124: MatCheckPreallocated(mat,1);
3126: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3127: (*mat->ops->solve)(mat,b,x);
3128: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3129: PetscObjectStateIncrease((PetscObject)x);
3130: return(0);
3131: }
3135: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3136: {
3138: Vec b,x;
3139: PetscInt m,N,i;
3140: PetscScalar *bb,*xx;
3141: PetscBool flg;
3144: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3145: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3146: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3147: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3149: MatDenseGetArray(B,&bb);
3150: MatDenseGetArray(X,&xx);
3151: MatGetLocalSize(B,&m,NULL); /* number local rows */
3152: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3153: MatGetVecs(A,&x,&b);
3154: for (i=0; i<N; i++) {
3155: VecPlaceArray(b,bb + i*m);
3156: VecPlaceArray(x,xx + i*m);
3157: MatSolve(A,b,x);
3158: VecResetArray(x);
3159: VecResetArray(b);
3160: }
3161: VecDestroy(&b);
3162: VecDestroy(&x);
3163: MatDenseRestoreArray(B,&bb);
3164: MatDenseRestoreArray(X,&xx);
3165: return(0);
3166: }
3170: /*@
3171: MatMatSolve - Solves A X = B, given a factored matrix.
3173: Neighbor-wise Collective on Mat
3175: Input Parameters:
3176: + mat - the factored matrix
3177: - B - the right-hand-side matrix (dense matrix)
3179: Output Parameter:
3180: . X - the result matrix (dense matrix)
3182: Notes:
3183: The matrices b and x cannot be the same. I.e., one cannot
3184: call MatMatSolve(A,x,x).
3186: Notes:
3187: Most users should usually employ the simplified KSP interface for linear solvers
3188: instead of working directly with matrix algebra routines such as this.
3189: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3190: at a time.
3192: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3193: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3195: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3197: Level: developer
3199: Concepts: matrices^triangular solves
3201: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3202: @*/
3203: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3204: {
3214: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3215: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216: 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);
3217: 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);
3218: 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);
3219: if (!A->rmap->N && !A->cmap->N) return(0);
3220: MatCheckPreallocated(A,1);
3222: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3223: if (!A->ops->matsolve) {
3224: PetscInfo1(A,"Mat type %s using basic MatMatSolve",((PetscObject)A)->type_name);
3225: MatMatSolve_Basic(A,B,X);
3226: } else {
3227: (*A->ops->matsolve)(A,B,X);
3228: }
3229: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3230: PetscObjectStateIncrease((PetscObject)X);
3231: return(0);
3232: }
3237: /*@
3238: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3239: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3241: Neighbor-wise Collective on Mat and Vec
3243: Input Parameters:
3244: + mat - the factored matrix
3245: - b - the right-hand-side vector
3247: Output Parameter:
3248: . x - the result vector
3250: Notes:
3251: MatSolve() should be used for most applications, as it performs
3252: a forward solve followed by a backward solve.
3254: The vectors b and x cannot be the same, i.e., one cannot
3255: call MatForwardSolve(A,x,x).
3257: For matrix in seqsbaij format with block size larger than 1,
3258: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3259: MatForwardSolve() solves U^T*D y = b, and
3260: MatBackwardSolve() solves U x = y.
3261: Thus they do not provide a symmetric preconditioner.
3263: Most users should employ the simplified KSP interface for linear solvers
3264: instead of working directly with matrix algebra routines such as this.
3265: See, e.g., KSPCreate().
3267: Level: developer
3269: Concepts: matrices^forward solves
3271: .seealso: MatSolve(), MatBackwardSolve()
3272: @*/
3273: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3274: {
3284: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3285: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3286: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3287: 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);
3288: 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);
3289: 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);
3290: MatCheckPreallocated(mat,1);
3291: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3292: (*mat->ops->forwardsolve)(mat,b,x);
3293: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3294: PetscObjectStateIncrease((PetscObject)x);
3295: return(0);
3296: }
3300: /*@
3301: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3302: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3304: Neighbor-wise Collective on Mat and Vec
3306: Input Parameters:
3307: + mat - the factored matrix
3308: - b - the right-hand-side vector
3310: Output Parameter:
3311: . x - the result vector
3313: Notes:
3314: MatSolve() should be used for most applications, as it performs
3315: a forward solve followed by a backward solve.
3317: The vectors b and x cannot be the same. I.e., one cannot
3318: call MatBackwardSolve(A,x,x).
3320: For matrix in seqsbaij format with block size larger than 1,
3321: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3322: MatForwardSolve() solves U^T*D y = b, and
3323: MatBackwardSolve() solves U x = y.
3324: Thus they do not provide a symmetric preconditioner.
3326: Most users should employ the simplified KSP interface for linear solvers
3327: instead of working directly with matrix algebra routines such as this.
3328: See, e.g., KSPCreate().
3330: Level: developer
3332: Concepts: matrices^backward solves
3334: .seealso: MatSolve(), MatForwardSolve()
3335: @*/
3336: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3337: {
3347: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3348: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3349: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3350: 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);
3351: 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);
3352: 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);
3353: MatCheckPreallocated(mat,1);
3355: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3356: (*mat->ops->backwardsolve)(mat,b,x);
3357: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3358: PetscObjectStateIncrease((PetscObject)x);
3359: return(0);
3360: }
3364: /*@
3365: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3367: Neighbor-wise Collective on Mat and Vec
3369: Input Parameters:
3370: + mat - the factored matrix
3371: . b - the right-hand-side vector
3372: - y - the vector to be added to
3374: Output Parameter:
3375: . x - the result vector
3377: Notes:
3378: The vectors b and x cannot be the same. I.e., one cannot
3379: call MatSolveAdd(A,x,y,x).
3381: Most users should employ the simplified KSP interface for linear solvers
3382: instead of working directly with matrix algebra routines such as this.
3383: See, e.g., KSPCreate().
3385: Level: developer
3387: Concepts: matrices^triangular solves
3389: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3390: @*/
3391: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3392: {
3393: PetscScalar one = 1.0;
3394: Vec tmp;
3406: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3407: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3408: 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);
3409: 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);
3410: 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);
3411: 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);
3412: 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);
3413: MatCheckPreallocated(mat,1);
3415: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3416: if (mat->ops->solveadd) {
3417: (*mat->ops->solveadd)(mat,b,y,x);
3418: } else {
3419: /* do the solve then the add manually */
3420: if (x != y) {
3421: MatSolve(mat,b,x);
3422: VecAXPY(x,one,y);
3423: } else {
3424: VecDuplicate(x,&tmp);
3425: PetscLogObjectParent(mat,tmp);
3426: VecCopy(x,tmp);
3427: MatSolve(mat,b,x);
3428: VecAXPY(x,one,tmp);
3429: VecDestroy(&tmp);
3430: }
3431: }
3432: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3433: PetscObjectStateIncrease((PetscObject)x);
3434: return(0);
3435: }
3439: /*@
3440: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3442: Neighbor-wise Collective on Mat and Vec
3444: Input Parameters:
3445: + mat - the factored matrix
3446: - b - the right-hand-side vector
3448: Output Parameter:
3449: . x - the result vector
3451: Notes:
3452: The vectors b and x cannot be the same. I.e., one cannot
3453: call MatSolveTranspose(A,x,x).
3455: Most users should employ the simplified KSP interface for linear solvers
3456: instead of working directly with matrix algebra routines such as this.
3457: See, e.g., KSPCreate().
3459: Level: developer
3461: Concepts: matrices^triangular solves
3463: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3464: @*/
3465: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3466: {
3476: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3477: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3478: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3479: 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);
3480: 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);
3481: MatCheckPreallocated(mat,1);
3482: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3483: (*mat->ops->solvetranspose)(mat,b,x);
3484: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3485: PetscObjectStateIncrease((PetscObject)x);
3486: return(0);
3487: }
3491: /*@
3492: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3493: factored matrix.
3495: Neighbor-wise Collective on Mat and Vec
3497: Input Parameters:
3498: + mat - the factored matrix
3499: . b - the right-hand-side vector
3500: - y - the vector to be added to
3502: Output Parameter:
3503: . x - the result vector
3505: Notes:
3506: The vectors b and x cannot be the same. I.e., one cannot
3507: call MatSolveTransposeAdd(A,x,y,x).
3509: Most users should employ the simplified KSP interface for linear solvers
3510: instead of working directly with matrix algebra routines such as this.
3511: See, e.g., KSPCreate().
3513: Level: developer
3515: Concepts: matrices^triangular solves
3517: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3518: @*/
3519: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3520: {
3521: PetscScalar one = 1.0;
3523: Vec tmp;
3534: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3535: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3536: 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);
3537: 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);
3538: 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);
3539: 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);
3540: MatCheckPreallocated(mat,1);
3542: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3543: if (mat->ops->solvetransposeadd) {
3544: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3545: } else {
3546: /* do the solve then the add manually */
3547: if (x != y) {
3548: MatSolveTranspose(mat,b,x);
3549: VecAXPY(x,one,y);
3550: } else {
3551: VecDuplicate(x,&tmp);
3552: PetscLogObjectParent(mat,tmp);
3553: VecCopy(x,tmp);
3554: MatSolveTranspose(mat,b,x);
3555: VecAXPY(x,one,tmp);
3556: VecDestroy(&tmp);
3557: }
3558: }
3559: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3560: PetscObjectStateIncrease((PetscObject)x);
3561: return(0);
3562: }
3563: /* ----------------------------------------------------------------*/
3567: /*@
3568: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3570: Neighbor-wise Collective on Mat and Vec
3572: Input Parameters:
3573: + mat - the matrix
3574: . b - the right hand side
3575: . omega - the relaxation factor
3576: . flag - flag indicating the type of SOR (see below)
3577: . shift - diagonal shift
3578: . its - the number of iterations
3579: - lits - the number of local iterations
3581: Output Parameters:
3582: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3584: SOR Flags:
3585: . SOR_FORWARD_SWEEP - forward SOR
3586: . SOR_BACKWARD_SWEEP - backward SOR
3587: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3588: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3589: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3590: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3591: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3592: upper/lower triangular part of matrix to
3593: vector (with omega)
3594: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3596: Notes:
3597: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3598: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3599: on each processor.
3601: Application programmers will not generally use MatSOR() directly,
3602: but instead will employ the KSP/PC interface.
3604: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3606: Notes for Advanced Users:
3607: The flags are implemented as bitwise inclusive or operations.
3608: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3609: to specify a zero initial guess for SSOR.
3611: Most users should employ the simplified KSP interface for linear solvers
3612: instead of working directly with matrix algebra routines such as this.
3613: See, e.g., KSPCreate().
3615: Vectors x and b CANNOT be the same
3617: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3619: Level: developer
3621: Concepts: matrices^relaxation
3622: Concepts: matrices^SOR
3623: Concepts: matrices^Gauss-Seidel
3625: @*/
3626: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3627: {
3637: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3638: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3639: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3640: 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);
3641: 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);
3642: 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);
3643: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3644: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3645: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3647: MatCheckPreallocated(mat,1);
3648: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3649: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3650: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3651: PetscObjectStateIncrease((PetscObject)x);
3652: return(0);
3653: }
3657: /*
3658: Default matrix copy routine.
3659: */
3660: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3661: {
3662: PetscErrorCode ierr;
3663: PetscInt i,rstart = 0,rend = 0,nz;
3664: const PetscInt *cwork;
3665: const PetscScalar *vwork;
3668: if (B->assembled) {
3669: MatZeroEntries(B);
3670: }
3671: MatGetOwnershipRange(A,&rstart,&rend);
3672: for (i=rstart; i<rend; i++) {
3673: MatGetRow(A,i,&nz,&cwork,&vwork);
3674: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3675: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3676: }
3677: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3678: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3679: PetscObjectStateIncrease((PetscObject)B);
3680: return(0);
3681: }
3685: /*@
3686: MatCopy - Copys a matrix to another matrix.
3688: Collective on Mat
3690: Input Parameters:
3691: + A - the matrix
3692: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3694: Output Parameter:
3695: . B - where the copy is put
3697: Notes:
3698: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3699: same nonzero pattern or the routine will crash.
3701: MatCopy() copies the matrix entries of a matrix to another existing
3702: matrix (after first zeroing the second matrix). A related routine is
3703: MatConvert(), which first creates a new matrix and then copies the data.
3705: Level: intermediate
3707: Concepts: matrices^copying
3709: .seealso: MatConvert(), MatDuplicate()
3711: @*/
3712: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3713: {
3715: PetscInt i;
3723: MatCheckPreallocated(B,2);
3724: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3725: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3726: 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);
3727: MatCheckPreallocated(A,1);
3729: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3730: if (A->ops->copy) {
3731: (*A->ops->copy)(A,B,str);
3732: } else { /* generic conversion */
3733: MatCopy_Basic(A,B,str);
3734: }
3736: B->stencil.dim = A->stencil.dim;
3737: B->stencil.noc = A->stencil.noc;
3738: for (i=0; i<=A->stencil.dim; i++) {
3739: B->stencil.dims[i] = A->stencil.dims[i];
3740: B->stencil.starts[i] = A->stencil.starts[i];
3741: }
3743: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3744: PetscObjectStateIncrease((PetscObject)B);
3745: return(0);
3746: }
3750: /*@C
3751: MatConvert - Converts a matrix to another matrix, either of the same
3752: or different type.
3754: Collective on Mat
3756: Input Parameters:
3757: + mat - the matrix
3758: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3759: same type as the original matrix.
3760: - reuse - denotes if the destination matrix is to be created or reused. Currently
3761: MAT_REUSE_MATRIX is only supported for inplace conversion, otherwise use
3762: MAT_INITIAL_MATRIX.
3764: Output Parameter:
3765: . M - pointer to place new matrix
3767: Notes:
3768: MatConvert() first creates a new matrix and then copies the data from
3769: the first matrix. A related routine is MatCopy(), which copies the matrix
3770: entries of one matrix to another already existing matrix context.
3772: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3773: the MPI communicator of the generated matrix is always the same as the communicator
3774: of the input matrix.
3776: Level: intermediate
3778: Concepts: matrices^converting between storage formats
3780: .seealso: MatCopy(), MatDuplicate()
3781: @*/
3782: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3783: {
3785: PetscBool sametype,issame,flg;
3786: char convname[256],mtype[256];
3787: Mat B;
3793: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3794: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3795: MatCheckPreallocated(mat,1);
3796: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3798: PetscOptionsGetString(((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3799: if (flg) {
3800: newtype = mtype;
3801: }
3802: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3803: PetscStrcmp(newtype,"same",&issame);
3804: if ((reuse == MAT_REUSE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX only supported for in-place conversion currently");
3806: if ((reuse == MAT_REUSE_MATRIX) && (issame || sametype)) return(0);
3808: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3809: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3810: } else {
3811: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3812: const char *prefix[3] = {"seq","mpi",""};
3813: PetscInt i;
3814: /*
3815: Order of precedence:
3816: 1) See if a specialized converter is known to the current matrix.
3817: 2) See if a specialized converter is known to the desired matrix class.
3818: 3) See if a good general converter is registered for the desired class
3819: (as of 6/27/03 only MATMPIADJ falls into this category).
3820: 4) See if a good general converter is known for the current matrix.
3821: 5) Use a really basic converter.
3822: */
3824: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3825: for (i=0; i<3; i++) {
3826: PetscStrcpy(convname,"MatConvert_");
3827: PetscStrcat(convname,((PetscObject)mat)->type_name);
3828: PetscStrcat(convname,"_");
3829: PetscStrcat(convname,prefix[i]);
3830: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3831: PetscStrcat(convname,"_C");
3832: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3833: if (conv) goto foundconv;
3834: }
3836: /* 2) See if a specialized converter is known to the desired matrix class. */
3837: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3838: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3839: MatSetType(B,newtype);
3840: for (i=0; i<3; i++) {
3841: PetscStrcpy(convname,"MatConvert_");
3842: PetscStrcat(convname,((PetscObject)mat)->type_name);
3843: PetscStrcat(convname,"_");
3844: PetscStrcat(convname,prefix[i]);
3845: PetscStrcat(convname,newtype);
3846: PetscStrcat(convname,"_C");
3847: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3848: if (conv) {
3849: MatDestroy(&B);
3850: goto foundconv;
3851: }
3852: }
3854: /* 3) See if a good general converter is registered for the desired class */
3855: conv = B->ops->convertfrom;
3856: MatDestroy(&B);
3857: if (conv) goto foundconv;
3859: /* 4) See if a good general converter is known for the current matrix */
3860: if (mat->ops->convert) {
3861: conv = mat->ops->convert;
3862: }
3863: if (conv) goto foundconv;
3865: /* 5) Use a really basic converter. */
3866: conv = MatConvert_Basic;
3868: foundconv:
3869: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3870: (*conv)(mat,newtype,reuse,M);
3871: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3872: }
3873: PetscObjectStateIncrease((PetscObject)*M);
3875: /* Copy Mat options */
3876: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3877: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3878: return(0);
3879: }
3883: /*@C
3884: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3886: Not Collective
3888: Input Parameter:
3889: . mat - the matrix, must be a factored matrix
3891: Output Parameter:
3892: . type - the string name of the package (do not free this string)
3894: Notes:
3895: In Fortran you pass in a empty string and the package name will be copied into it.
3896: (Make sure the string is long enough)
3898: Level: intermediate
3900: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
3901: @*/
3902: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
3903: {
3904: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
3909: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
3910: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
3911: if (!conv) {
3912: *type = MATSOLVERPETSC;
3913: } else {
3914: (*conv)(mat,type);
3915: }
3916: return(0);
3917: }
3921: /*@C
3922: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
3924: Collective on Mat
3926: Input Parameters:
3927: + mat - the matrix
3928: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3929: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3931: Output Parameters:
3932: . f - the factor matrix used with MatXXFactorSymbolic() calls
3934: Notes:
3935: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3936: such as pastix, superlu, mumps etc.
3938: PETSc must have been ./configure to use the external solver, using the option --download-package
3940: Level: intermediate
3942: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
3943: @*/
3944: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
3945: {
3946: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
3947: char convname[256];
3953: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3954: MatCheckPreallocated(mat,1);
3956: PetscStrcpy(convname,"MatGetFactor_");
3957: PetscStrcat(convname,type);
3958: PetscStrcat(convname,"_C");
3959: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3960: if (!conv) {
3961: PetscBool flag;
3962: MPI_Comm comm;
3964: PetscObjectGetComm((PetscObject)mat,&comm);
3965: PetscStrcasecmp(MATSOLVERPETSC,type,&flag);
3966: if (flag) SETERRQ2(comm,PETSC_ERR_SUP,"Matrix format %s does not have a built-in PETSc %s",((PetscObject)mat)->type_name,MatFactorTypes[ftype]);
3967: else SETERRQ4(comm,PETSC_ERR_SUP,"Matrix format %s does not have a solver package %s for %s. Perhaps you must ./configure with --download-%s",((PetscObject)mat)->type_name,type,MatFactorTypes[ftype],type);
3968: }
3969: (*conv)(mat,ftype,f);
3970: return(0);
3971: }
3975: /*@C
3976: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
3978: Not Collective
3980: Input Parameters:
3981: + mat - the matrix
3982: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
3983: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
3985: Output Parameter:
3986: . flg - PETSC_TRUE if the factorization is available
3988: Notes:
3989: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
3990: such as pastix, superlu, mumps etc.
3992: PETSc must have been ./configure to use the external solver, using the option --download-package
3994: Level: intermediate
3996: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
3997: @*/
3998: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
3999: {
4000: PetscErrorCode ierr, (*conv)(Mat,MatFactorType,PetscBool*);
4001: char convname[256];
4007: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4008: MatCheckPreallocated(mat,1);
4010: PetscStrcpy(convname,"MatGetFactorAvailable_");
4011: PetscStrcat(convname,type);
4012: PetscStrcat(convname,"_C");
4013: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4014: if (!conv) {
4015: *flg = PETSC_FALSE;
4016: } else {
4017: (*conv)(mat,ftype,flg);
4018: }
4019: return(0);
4020: }
4025: /*@
4026: MatDuplicate - Duplicates a matrix including the non-zero structure.
4028: Collective on Mat
4030: Input Parameters:
4031: + mat - the matrix
4032: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4033: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4035: Output Parameter:
4036: . M - pointer to place new matrix
4038: Level: intermediate
4040: Concepts: matrices^duplicating
4042: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4044: .seealso: MatCopy(), MatConvert()
4045: @*/
4046: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4047: {
4049: Mat B;
4050: PetscInt i;
4056: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4057: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4058: MatCheckPreallocated(mat,1);
4060: *M = 0;
4061: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4062: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4063: (*mat->ops->duplicate)(mat,op,M);
4064: B = *M;
4066: B->stencil.dim = mat->stencil.dim;
4067: B->stencil.noc = mat->stencil.noc;
4068: for (i=0; i<=mat->stencil.dim; i++) {
4069: B->stencil.dims[i] = mat->stencil.dims[i];
4070: B->stencil.starts[i] = mat->stencil.starts[i];
4071: }
4073: B->nooffproczerorows = mat->nooffproczerorows;
4074: B->nooffprocentries = mat->nooffprocentries;
4076: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4077: PetscObjectStateIncrease((PetscObject)B);
4078: return(0);
4079: }
4083: /*@
4084: MatGetDiagonal - Gets the diagonal of a matrix.
4086: Logically Collective on Mat and Vec
4088: Input Parameters:
4089: + mat - the matrix
4090: - v - the vector for storing the diagonal
4092: Output Parameter:
4093: . v - the diagonal of the matrix
4095: Level: intermediate
4097: Note:
4098: Currently only correct in parallel for square matrices.
4100: Concepts: matrices^accessing diagonals
4102: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4103: @*/
4104: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4105: {
4112: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4113: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4114: MatCheckPreallocated(mat,1);
4116: (*mat->ops->getdiagonal)(mat,v);
4117: PetscObjectStateIncrease((PetscObject)v);
4118: return(0);
4119: }
4123: /*@
4124: MatGetRowMin - Gets the minimum value (of the real part) of each
4125: row of the matrix
4127: Logically Collective on Mat and Vec
4129: Input Parameters:
4130: . mat - the matrix
4132: Output Parameter:
4133: + v - the vector for storing the maximums
4134: - idx - the indices of the column found for each row (optional)
4136: Level: intermediate
4138: Notes: The result of this call are the same as if one converted the matrix to dense format
4139: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4141: This code is only implemented for a couple of matrix formats.
4143: Concepts: matrices^getting row maximums
4145: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4146: MatGetRowMax()
4147: @*/
4148: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4149: {
4156: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4157: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4158: MatCheckPreallocated(mat,1);
4160: (*mat->ops->getrowmin)(mat,v,idx);
4161: PetscObjectStateIncrease((PetscObject)v);
4162: return(0);
4163: }
4167: /*@
4168: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4169: row of the matrix
4171: Logically Collective on Mat and Vec
4173: Input Parameters:
4174: . mat - the matrix
4176: Output Parameter:
4177: + v - the vector for storing the minimums
4178: - idx - the indices of the column found for each row (or NULL if not needed)
4180: Level: intermediate
4182: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4183: row is 0 (the first column).
4185: This code is only implemented for a couple of matrix formats.
4187: Concepts: matrices^getting row maximums
4189: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4190: @*/
4191: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4192: {
4199: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4200: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4201: MatCheckPreallocated(mat,1);
4202: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4204: (*mat->ops->getrowminabs)(mat,v,idx);
4205: PetscObjectStateIncrease((PetscObject)v);
4206: return(0);
4207: }
4211: /*@
4212: MatGetRowMax - Gets the maximum value (of the real part) of each
4213: row of the matrix
4215: Logically Collective on Mat and Vec
4217: Input Parameters:
4218: . mat - the matrix
4220: Output Parameter:
4221: + v - the vector for storing the maximums
4222: - idx - the indices of the column found for each row (optional)
4224: Level: intermediate
4226: Notes: The result of this call are the same as if one converted the matrix to dense format
4227: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4229: This code is only implemented for a couple of matrix formats.
4231: Concepts: matrices^getting row maximums
4233: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4234: @*/
4235: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4236: {
4243: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4244: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4245: MatCheckPreallocated(mat,1);
4247: (*mat->ops->getrowmax)(mat,v,idx);
4248: PetscObjectStateIncrease((PetscObject)v);
4249: return(0);
4250: }
4254: /*@
4255: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4256: row of the matrix
4258: Logically Collective on Mat and Vec
4260: Input Parameters:
4261: . mat - the matrix
4263: Output Parameter:
4264: + v - the vector for storing the maximums
4265: - idx - the indices of the column found for each row (or NULL if not needed)
4267: Level: intermediate
4269: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4270: row is 0 (the first column).
4272: This code is only implemented for a couple of matrix formats.
4274: Concepts: matrices^getting row maximums
4276: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4277: @*/
4278: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4279: {
4286: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4287: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4288: MatCheckPreallocated(mat,1);
4289: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4291: (*mat->ops->getrowmaxabs)(mat,v,idx);
4292: PetscObjectStateIncrease((PetscObject)v);
4293: return(0);
4294: }
4298: /*@
4299: MatGetRowSum - Gets the sum of each row of the matrix
4301: Logically Collective on Mat and Vec
4303: Input Parameters:
4304: . mat - the matrix
4306: Output Parameter:
4307: . v - the vector for storing the sum of rows
4309: Level: intermediate
4311: Notes: This code is slow since it is not currently specialized for different formats
4313: Concepts: matrices^getting row sums
4315: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4316: @*/
4317: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4318: {
4319: PetscInt start = 0, end = 0, row;
4320: PetscScalar *array;
4327: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4328: MatCheckPreallocated(mat,1);
4329: MatGetOwnershipRange(mat, &start, &end);
4330: VecGetArray(v, &array);
4331: for (row = start; row < end; ++row) {
4332: PetscInt ncols, col;
4333: const PetscInt *cols;
4334: const PetscScalar *vals;
4336: array[row - start] = 0.0;
4338: MatGetRow(mat, row, &ncols, &cols, &vals);
4339: for (col = 0; col < ncols; col++) {
4340: array[row - start] += vals[col];
4341: }
4342: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4343: }
4344: VecRestoreArray(v, &array);
4345: PetscObjectStateIncrease((PetscObject) v);
4346: return(0);
4347: }
4351: /*@
4352: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4354: Collective on Mat
4356: Input Parameter:
4357: + mat - the matrix to transpose
4358: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4360: Output Parameters:
4361: . B - the transpose
4363: Notes:
4364: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4366: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4368: Level: intermediate
4370: Concepts: matrices^transposing
4372: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4373: @*/
4374: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4375: {
4381: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4382: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4383: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4384: MatCheckPreallocated(mat,1);
4386: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4387: (*mat->ops->transpose)(mat,reuse,B);
4388: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4389: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4390: return(0);
4391: }
4395: /*@
4396: MatIsTranspose - Test whether a matrix is another one's transpose,
4397: or its own, in which case it tests symmetry.
4399: Collective on Mat
4401: Input Parameter:
4402: + A - the matrix to test
4403: - B - the matrix to test against, this can equal the first parameter
4405: Output Parameters:
4406: . flg - the result
4408: Notes:
4409: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4410: has a running time of the order of the number of nonzeros; the parallel
4411: test involves parallel copies of the block-offdiagonal parts of the matrix.
4413: Level: intermediate
4415: Concepts: matrices^transposing, matrix^symmetry
4417: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4418: @*/
4419: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4420: {
4421: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4427: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4428: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4429: *flg = PETSC_FALSE;
4430: if (f && g) {
4431: if (f == g) {
4432: (*f)(A,B,tol,flg);
4433: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4434: } else {
4435: MatType mattype;
4436: if (!f) {
4437: MatGetType(A,&mattype);
4438: } else {
4439: MatGetType(B,&mattype);
4440: }
4441: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4442: }
4443: return(0);
4444: }
4448: /*@
4449: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4451: Collective on Mat
4453: Input Parameter:
4454: + mat - the matrix to transpose and complex conjugate
4455: - reuse - store the transpose matrix in the provided B
4457: Output Parameters:
4458: . B - the Hermitian
4460: Notes:
4461: If you pass in &mat for B the Hermitian will be done in place
4463: Level: intermediate
4465: Concepts: matrices^transposing, complex conjugatex
4467: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4468: @*/
4469: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4470: {
4474: MatTranspose(mat,reuse,B);
4475: #if defined(PETSC_USE_COMPLEX)
4476: MatConjugate(*B);
4477: #endif
4478: return(0);
4479: }
4483: /*@
4484: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4486: Collective on Mat
4488: Input Parameter:
4489: + A - the matrix to test
4490: - B - the matrix to test against, this can equal the first parameter
4492: Output Parameters:
4493: . flg - the result
4495: Notes:
4496: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4497: has a running time of the order of the number of nonzeros; the parallel
4498: test involves parallel copies of the block-offdiagonal parts of the matrix.
4500: Level: intermediate
4502: Concepts: matrices^transposing, matrix^symmetry
4504: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4505: @*/
4506: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4507: {
4508: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4514: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4515: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4516: if (f && g) {
4517: if (f==g) {
4518: (*f)(A,B,tol,flg);
4519: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4520: }
4521: return(0);
4522: }
4526: /*@
4527: MatPermute - Creates a new matrix with rows and columns permuted from the
4528: original.
4530: Collective on Mat
4532: Input Parameters:
4533: + mat - the matrix to permute
4534: . row - row permutation, each processor supplies only the permutation for its rows
4535: - col - column permutation, each processor supplies only the permutation for its columns
4537: Output Parameters:
4538: . B - the permuted matrix
4540: Level: advanced
4542: Note:
4543: The index sets map from row/col of permuted matrix to row/col of original matrix.
4544: The index sets should be on the same communicator as Mat and have the same local sizes.
4546: Concepts: matrices^permuting
4548: .seealso: MatGetOrdering(), ISAllGather()
4550: @*/
4551: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4552: {
4561: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4562: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4563: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4564: MatCheckPreallocated(mat,1);
4566: (*mat->ops->permute)(mat,row,col,B);
4567: PetscObjectStateIncrease((PetscObject)*B);
4568: return(0);
4569: }
4573: /*@
4574: MatEqual - Compares two matrices.
4576: Collective on Mat
4578: Input Parameters:
4579: + A - the first matrix
4580: - B - the second matrix
4582: Output Parameter:
4583: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4585: Level: intermediate
4587: Concepts: matrices^equality between
4588: @*/
4589: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4590: {
4600: MatCheckPreallocated(B,2);
4601: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4602: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4603: 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);
4604: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4605: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4606: 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);
4607: MatCheckPreallocated(A,1);
4609: (*A->ops->equal)(A,B,flg);
4610: return(0);
4611: }
4615: /*@
4616: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4617: matrices that are stored as vectors. Either of the two scaling
4618: matrices can be NULL.
4620: Collective on Mat
4622: Input Parameters:
4623: + mat - the matrix to be scaled
4624: . l - the left scaling vector (or NULL)
4625: - r - the right scaling vector (or NULL)
4627: Notes:
4628: MatDiagonalScale() computes A = LAR, where
4629: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4630: The L scales the rows of the matrix, the R scales the columns of the matrix.
4632: Level: intermediate
4634: Concepts: matrices^diagonal scaling
4635: Concepts: diagonal scaling of matrices
4637: .seealso: MatScale()
4638: @*/
4639: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4640: {
4646: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4649: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4650: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4651: MatCheckPreallocated(mat,1);
4653: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4654: (*mat->ops->diagonalscale)(mat,l,r);
4655: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4656: PetscObjectStateIncrease((PetscObject)mat);
4657: #if defined(PETSC_HAVE_CUSP)
4658: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4659: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4660: }
4661: #endif
4662: return(0);
4663: }
4667: /*@
4668: MatScale - Scales all elements of a matrix by a given number.
4670: Logically Collective on Mat
4672: Input Parameters:
4673: + mat - the matrix to be scaled
4674: - a - the scaling value
4676: Output Parameter:
4677: . mat - the scaled matrix
4679: Level: intermediate
4681: Concepts: matrices^scaling all entries
4683: .seealso: MatDiagonalScale()
4684: @*/
4685: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4686: {
4692: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4693: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4694: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4696: MatCheckPreallocated(mat,1);
4698: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4699: if (a != (PetscScalar)1.0) {
4700: (*mat->ops->scale)(mat,a);
4701: PetscObjectStateIncrease((PetscObject)mat);
4702: }
4703: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4704: #if defined(PETSC_HAVE_CUSP)
4705: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4706: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4707: }
4708: #endif
4709: return(0);
4710: }
4714: /*@
4715: MatNorm - Calculates various norms of a matrix.
4717: Collective on Mat
4719: Input Parameters:
4720: + mat - the matrix
4721: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
4723: Output Parameters:
4724: . nrm - the resulting norm
4726: Level: intermediate
4728: Concepts: matrices^norm
4729: Concepts: norm^of matrix
4730: @*/
4731: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
4732: {
4740: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4741: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4742: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4743: MatCheckPreallocated(mat,1);
4745: (*mat->ops->norm)(mat,type,nrm);
4746: return(0);
4747: }
4749: /*
4750: This variable is used to prevent counting of MatAssemblyBegin() that
4751: are called from within a MatAssemblyEnd().
4752: */
4753: static PetscInt MatAssemblyEnd_InUse = 0;
4756: /*@
4757: MatAssemblyBegin - Begins assembling the matrix. This routine should
4758: be called after completing all calls to MatSetValues().
4760: Collective on Mat
4762: Input Parameters:
4763: + mat - the matrix
4764: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4766: Notes:
4767: MatSetValues() generally caches the values. The matrix is ready to
4768: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4769: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4770: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4771: using the matrix.
4773: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
4774: 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
4775: a global collective operation requring all processes that share the matrix.
4777: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4778: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4779: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4781: Level: beginner
4783: Concepts: matrices^assembling
4785: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
4786: @*/
4787: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
4788: {
4794: MatCheckPreallocated(mat,1);
4795: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
4796: if (mat->assembled) {
4797: mat->was_assembled = PETSC_TRUE;
4798: mat->assembled = PETSC_FALSE;
4799: }
4800: if (!MatAssemblyEnd_InUse) {
4801: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
4802: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
4803: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
4804: } else if (mat->ops->assemblybegin) {
4805: (*mat->ops->assemblybegin)(mat,type);
4806: }
4807: return(0);
4808: }
4812: /*@
4813: MatAssembled - Indicates if a matrix has been assembled and is ready for
4814: use; for example, in matrix-vector product.
4816: Not Collective
4818: Input Parameter:
4819: . mat - the matrix
4821: Output Parameter:
4822: . assembled - PETSC_TRUE or PETSC_FALSE
4824: Level: advanced
4826: Concepts: matrices^assembled?
4828: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
4829: @*/
4830: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
4831: {
4836: *assembled = mat->assembled;
4837: return(0);
4838: }
4842: /*
4843: MatViewFromOptions - Processes command line options to determine if/how a matrix is to be viewed. Called from higher level packages.
4845: Collective on Vec
4847: Input Parameters:
4848: + mat - the matrix
4849: . prefix - prefix to use for viewing, or NULL to use prefix of 'mat'
4850: - optionname - option to activate viewing
4852: Level: intermediate
4854: .keywords: Mat, view, options, database
4855: .seealso: MatViewFromOptions()
4856: */
4857: PetscErrorCode MatViewFromOptions(Mat mat,const char prefix[],const char optionname[])
4858: {
4859: PetscErrorCode ierr;
4860: PetscViewer viewer;
4861: PetscBool flg;
4862: static PetscBool incall = PETSC_FALSE;
4863: PetscViewerFormat format;
4866: if (incall) return(0);
4867: incall = PETSC_TRUE;
4868: if (prefix) {
4869: PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),prefix,optionname,&viewer,&format,&flg);
4870: } else {
4871: PetscOptionsGetViewer(PetscObjectComm((PetscObject)mat),((PetscObject)mat)->prefix,optionname,&viewer,&format,&flg);
4872: }
4873: if (flg) {
4874: PetscViewerPushFormat(viewer,format);
4875: MatView(mat,viewer);
4876: PetscViewerPopFormat(viewer);
4877: PetscViewerDestroy(&viewer);
4878: }
4879: incall = PETSC_FALSE;
4880: return(0);
4881: }
4885: /*@
4886: MatAssemblyEnd - Completes assembling the matrix. This routine should
4887: be called after MatAssemblyBegin().
4889: Collective on Mat
4891: Input Parameters:
4892: + mat - the matrix
4893: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
4895: Options Database Keys:
4896: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
4897: . -mat_view ::ascii_info_detail - Prints more detailed info
4898: . -mat_view - Prints matrix in ASCII format
4899: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
4900: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
4901: . -display <name> - Sets display name (default is host)
4902: . -draw_pause <sec> - Sets number of seconds to pause after display
4903: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See the <a href="../../docs/manual.pdf">users manual</a>)
4904: . -viewer_socket_machine <machine>
4905: . -viewer_socket_port <port>
4906: . -mat_view binary - save matrix to file in binary format
4907: - -viewer_binary_filename <name>
4909: Notes:
4910: MatSetValues() generally caches the values. The matrix is ready to
4911: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
4912: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
4913: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
4914: using the matrix.
4916: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
4917: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
4918: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
4920: Level: beginner
4922: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
4923: @*/
4924: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
4925: {
4926: PetscErrorCode ierr;
4927: static PetscInt inassm = 0;
4928: PetscBool flg = PETSC_FALSE;
4934: inassm++;
4935: MatAssemblyEnd_InUse++;
4936: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
4937: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
4938: if (mat->ops->assemblyend) {
4939: (*mat->ops->assemblyend)(mat,type);
4940: }
4941: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
4942: } else if (mat->ops->assemblyend) {
4943: (*mat->ops->assemblyend)(mat,type);
4944: }
4946: /* Flush assembly is not a true assembly */
4947: if (type != MAT_FLUSH_ASSEMBLY) {
4948: mat->assembled = PETSC_TRUE; mat->num_ass++;
4949: }
4950: mat->insertmode = NOT_SET_VALUES;
4951: MatAssemblyEnd_InUse--;
4952: PetscObjectStateIncrease((PetscObject)mat);
4953: if (!mat->symmetric_eternal) {
4954: mat->symmetric_set = PETSC_FALSE;
4955: mat->hermitian_set = PETSC_FALSE;
4956: mat->structurally_symmetric_set = PETSC_FALSE;
4957: }
4958: #if defined(PETSC_HAVE_CUSP)
4959: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4960: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4961: }
4962: #endif
4963: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
4964: if (mat->viewonassembly) {
4965: PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
4966: MatView(mat,mat->viewonassembly);
4967: PetscViewerPopFormat(mat->viewonassembly);
4968: }
4970: if (mat->checksymmetryonassembly) {
4971: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
4972: if (flg) {
4973: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %G)\n",mat->checksymmetrytol);
4974: } else {
4975: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %G)\n",mat->checksymmetrytol);
4976: }
4977: }
4978: if (mat->nullsp && mat->checknullspaceonassembly) {
4979: MatNullSpaceTest(mat->nullsp,mat,NULL);
4980: }
4981: }
4982: inassm--;
4983: return(0);
4984: }
4988: /*@
4989: MatSetOption - Sets a parameter option for a matrix. Some options
4990: may be specific to certain storage formats. Some options
4991: determine how values will be inserted (or added). Sorted,
4992: row-oriented input will generally assemble the fastest. The default
4993: is row-oriented.
4995: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
4997: Input Parameters:
4998: + mat - the matrix
4999: . option - the option, one of those listed below (and possibly others),
5000: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5002: Options Describing Matrix Structure:
5003: + MAT_SPD - symmetric positive definite
5004: - MAT_SYMMETRIC - symmetric in terms of both structure and value
5005: . MAT_HERMITIAN - transpose is the complex conjugation
5006: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5007: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5008: you set to be kept with all future use of the matrix
5009: including after MatAssemblyBegin/End() which could
5010: potentially change the symmetry structure, i.e. you
5011: KNOW the matrix will ALWAYS have the property you set.
5014: Options For Use with MatSetValues():
5015: Insert a logically dense subblock, which can be
5016: . MAT_ROW_ORIENTED - row-oriented (default)
5018: Note these options reflect the data you pass in with MatSetValues(); it has
5019: nothing to do with how the data is stored internally in the matrix
5020: data structure.
5022: When (re)assembling a matrix, we can restrict the input for
5023: efficiency/debugging purposes. These options include
5024: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be
5025: allowed if they generate a new nonzero
5026: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5027: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5028: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5029: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5030: + MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5031: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5032: performance for very large process counts.
5034: Notes:
5035: Some options are relevant only for particular matrix types and
5036: are thus ignored by others. Other options are not supported by
5037: certain matrix types and will generate an error message if set.
5039: If using a Fortran 77 module to compute a matrix, one may need to
5040: use the column-oriented option (or convert to the row-oriented
5041: format).
5043: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5044: that would generate a new entry in the nonzero structure is instead
5045: ignored. Thus, if memory has not alredy been allocated for this particular
5046: data, then the insertion is ignored. For dense matrices, in which
5047: the entire array is allocated, no entries are ever ignored.
5048: Set after the first MatAssemblyEnd()
5050: MAT_NEW_NONZERO_LOCATION_ERR indicates that any add or insertion
5051: that would generate a new entry in the nonzero structure instead produces
5052: an error. (Currently supported for AIJ and BAIJ formats only.)
5053: This is a useful flag when using SAME_NONZERO_PATTERN in calling
5054: KSPSetOperators() to ensure that the nonzero pattern truely does
5055: remain unchanged. Set after the first MatAssemblyEnd()
5057: MAT_NEW_NONZERO_ALLOCATION_ERR indicates that any add or insertion
5058: that would generate a new entry that has not been preallocated will
5059: instead produce an error. (Currently supported for AIJ and BAIJ formats
5060: only.) This is a useful flag when debugging matrix memory preallocation.
5062: MAT_IGNORE_OFF_PROC_ENTRIES indicates entries destined for
5063: other processors should be dropped, rather than stashed.
5064: This is useful if you know that the "owning" processor is also
5065: always generating the correct matrix entries, so that PETSc need
5066: not transfer duplicate entries generated on another processor.
5068: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5069: searches during matrix assembly. When this flag is set, the hash table
5070: is created during the first Matrix Assembly. This hash table is
5071: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5072: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5073: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5074: supported by MATMPIBAIJ format only.
5076: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5077: are kept in the nonzero structure
5079: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5080: a zero location in the matrix
5082: MAT_USE_INODES - indicates using inode version of the code - works with AIJ and
5083: ROWBS matrix types
5085: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5086: zero row routines and thus improves performance for very large process counts.
5088: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5089: part of the matrix (since they should match the upper triangular part).
5091: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5093: Level: intermediate
5095: Concepts: matrices^setting options
5097: .seealso: MatOption, Mat
5099: @*/
5100: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5101: {
5107: if (op > 0) {
5110: }
5112: 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);
5113: 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()");
5115: switch (op) {
5116: case MAT_NO_OFF_PROC_ENTRIES:
5117: mat->nooffprocentries = flg;
5118: return(0);
5119: break;
5120: case MAT_NO_OFF_PROC_ZERO_ROWS:
5121: mat->nooffproczerorows = flg;
5122: return(0);
5123: break;
5124: case MAT_SPD:
5125: mat->spd_set = PETSC_TRUE;
5126: mat->spd = flg;
5127: if (flg) {
5128: mat->symmetric = PETSC_TRUE;
5129: mat->structurally_symmetric = PETSC_TRUE;
5130: mat->symmetric_set = PETSC_TRUE;
5131: mat->structurally_symmetric_set = PETSC_TRUE;
5132: }
5133: break;
5134: case MAT_SYMMETRIC:
5135: mat->symmetric = flg;
5136: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5137: mat->symmetric_set = PETSC_TRUE;
5138: mat->structurally_symmetric_set = flg;
5139: break;
5140: case MAT_HERMITIAN:
5141: mat->hermitian = flg;
5142: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5143: mat->hermitian_set = PETSC_TRUE;
5144: mat->structurally_symmetric_set = flg;
5145: break;
5146: case MAT_STRUCTURALLY_SYMMETRIC:
5147: mat->structurally_symmetric = flg;
5148: mat->structurally_symmetric_set = PETSC_TRUE;
5149: break;
5150: case MAT_SYMMETRY_ETERNAL:
5151: mat->symmetric_eternal = flg;
5152: break;
5153: default:
5154: break;
5155: }
5156: if (mat->ops->setoption) {
5157: (*mat->ops->setoption)(mat,op,flg);
5158: }
5159: return(0);
5160: }
5164: /*@
5165: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5166: this routine retains the old nonzero structure.
5168: Logically Collective on Mat
5170: Input Parameters:
5171: . mat - the matrix
5173: Level: intermediate
5175: 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.
5176: See the Performance chapter of the users manual for information on preallocating matrices.
5178: Concepts: matrices^zeroing
5180: .seealso: MatZeroRows()
5181: @*/
5182: PetscErrorCode MatZeroEntries(Mat mat)
5183: {
5189: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5190: 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");
5191: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5192: MatCheckPreallocated(mat,1);
5194: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5195: (*mat->ops->zeroentries)(mat);
5196: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5197: PetscObjectStateIncrease((PetscObject)mat);
5198: #if defined(PETSC_HAVE_CUSP)
5199: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5200: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5201: }
5202: #endif
5203: return(0);
5204: }
5208: /*@C
5209: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5210: of a set of rows and columns of a matrix.
5212: Collective on Mat
5214: Input Parameters:
5215: + mat - the matrix
5216: . numRows - the number of rows to remove
5217: . rows - the global row indices
5218: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5219: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5220: - b - optional vector of right hand side, that will be adjusted by provided solution
5222: Notes:
5223: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5225: The user can set a value in the diagonal entry (or for the AIJ and
5226: row formats can optionally remove the main diagonal entry from the
5227: nonzero structure as well, by passing 0.0 as the final argument).
5229: For the parallel case, all processes that share the matrix (i.e.,
5230: those in the communicator used for matrix creation) MUST call this
5231: routine, regardless of whether any rows being zeroed are owned by
5232: them.
5234: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5235: list only rows local to itself).
5237: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5239: Level: intermediate
5241: Concepts: matrices^zeroing rows
5243: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5244: @*/
5245: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5246: {
5253: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5254: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5255: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5256: MatCheckPreallocated(mat,1);
5258: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5259: if (mat->viewonassembly) {
5260: PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
5261: MatView(mat,mat->viewonassembly);
5262: PetscViewerPopFormat(mat->viewonassembly);
5263: }
5264: PetscObjectStateIncrease((PetscObject)mat);
5265: #if defined(PETSC_HAVE_CUSP)
5266: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5267: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5268: }
5269: #endif
5270: return(0);
5271: }
5275: /*@C
5276: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5277: of a set of rows and columns of a matrix.
5279: Collective on Mat
5281: Input Parameters:
5282: + mat - the matrix
5283: . is - the rows to zero
5284: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5285: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5286: - b - optional vector of right hand side, that will be adjusted by provided solution
5288: Notes:
5289: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5291: The user can set a value in the diagonal entry (or for the AIJ and
5292: row formats can optionally remove the main diagonal entry from the
5293: nonzero structure as well, by passing 0.0 as the final argument).
5295: For the parallel case, all processes that share the matrix (i.e.,
5296: those in the communicator used for matrix creation) MUST call this
5297: routine, regardless of whether any rows being zeroed are owned by
5298: them.
5300: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5301: list only rows local to itself).
5303: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5305: Level: intermediate
5307: Concepts: matrices^zeroing rows
5309: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5310: @*/
5311: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5312: {
5314: PetscInt numRows;
5315: const PetscInt *rows;
5322: ISGetLocalSize(is,&numRows);
5323: ISGetIndices(is,&rows);
5324: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5325: ISRestoreIndices(is,&rows);
5326: return(0);
5327: }
5331: /*@C
5332: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5333: of a set of rows of a matrix.
5335: Collective on Mat
5337: Input Parameters:
5338: + mat - the matrix
5339: . numRows - the number of rows to remove
5340: . rows - the global row indices
5341: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5342: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5343: - b - optional vector of right hand side, that will be adjusted by provided solution
5345: Notes:
5346: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5347: but does not release memory. For the dense and block diagonal
5348: formats this does not alter the nonzero structure.
5350: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5351: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5352: merely zeroed.
5354: The user can set a value in the diagonal entry (or for the AIJ and
5355: row formats can optionally remove the main diagonal entry from the
5356: nonzero structure as well, by passing 0.0 as the final argument).
5358: For the parallel case, all processes that share the matrix (i.e.,
5359: those in the communicator used for matrix creation) MUST call this
5360: routine, regardless of whether any rows being zeroed are owned by
5361: them.
5363: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5364: list only rows local to itself).
5366: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5367: owns that are to be zeroed. This saves a global synchronization in the implementation.
5369: Level: intermediate
5371: Concepts: matrices^zeroing rows
5373: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5374: @*/
5375: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5376: {
5383: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5384: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5385: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5386: MatCheckPreallocated(mat,1);
5388: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5389: if (mat->viewonassembly) {
5390: PetscViewerPushFormat(mat->viewonassembly,mat->viewformatonassembly);
5391: MatView(mat,mat->viewonassembly);
5392: PetscViewerPopFormat(mat->viewonassembly);
5393: }
5394: PetscObjectStateIncrease((PetscObject)mat);
5395: #if defined(PETSC_HAVE_CUSP)
5396: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5397: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5398: }
5399: #endif
5400: return(0);
5401: }
5405: /*@C
5406: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5407: of a set of rows of a matrix.
5409: Collective on Mat
5411: Input Parameters:
5412: + mat - the matrix
5413: . is - index set of rows to remove
5414: . diag - value put in all diagonals of eliminated rows
5415: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5416: - b - optional vector of right hand side, that will be adjusted by provided solution
5418: Notes:
5419: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5420: but does not release memory. For the dense and block diagonal
5421: formats this does not alter the nonzero structure.
5423: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5424: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5425: merely zeroed.
5427: The user can set a value in the diagonal entry (or for the AIJ and
5428: row formats can optionally remove the main diagonal entry from the
5429: nonzero structure as well, by passing 0.0 as the final argument).
5431: For the parallel case, all processes that share the matrix (i.e.,
5432: those in the communicator used for matrix creation) MUST call this
5433: routine, regardless of whether any rows being zeroed are owned by
5434: them.
5436: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5437: list only rows local to itself).
5439: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5440: owns that are to be zeroed. This saves a global synchronization in the implementation.
5442: Level: intermediate
5444: Concepts: matrices^zeroing rows
5446: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5447: @*/
5448: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5449: {
5450: PetscInt numRows;
5451: const PetscInt *rows;
5458: ISGetLocalSize(is,&numRows);
5459: ISGetIndices(is,&rows);
5460: MatZeroRows(mat,numRows,rows,diag,x,b);
5461: ISRestoreIndices(is,&rows);
5462: return(0);
5463: }
5467: /*@C
5468: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5469: of a set of rows of a matrix. These rows must be local to the process.
5471: Collective on Mat
5473: Input Parameters:
5474: + mat - the matrix
5475: . numRows - the number of rows to remove
5476: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5477: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5478: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5479: - b - optional vector of right hand side, that will be adjusted by provided solution
5481: Notes:
5482: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5483: but does not release memory. For the dense and block diagonal
5484: formats this does not alter the nonzero structure.
5486: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5487: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5488: merely zeroed.
5490: The user can set a value in the diagonal entry (or for the AIJ and
5491: row formats can optionally remove the main diagonal entry from the
5492: nonzero structure as well, by passing 0.0 as the final argument).
5494: For the parallel case, all processes that share the matrix (i.e.,
5495: those in the communicator used for matrix creation) MUST call this
5496: routine, regardless of whether any rows being zeroed are owned by
5497: them.
5499: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5500: list only rows local to itself).
5502: The grid coordinates are across the entire grid, not just the local portion
5504: In Fortran idxm and idxn should be declared as
5505: $ MatStencil idxm(4,m)
5506: and the values inserted using
5507: $ idxm(MatStencil_i,1) = i
5508: $ idxm(MatStencil_j,1) = j
5509: $ idxm(MatStencil_k,1) = k
5510: $ idxm(MatStencil_c,1) = c
5511: etc
5513: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5514: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5515: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5516: DMDA_BOUNDARY_PERIODIC boundary type.
5518: 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
5519: a single value per point) you can skip filling those indices.
5521: Level: intermediate
5523: Concepts: matrices^zeroing rows
5525: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5526: @*/
5527: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5528: {
5529: PetscInt dim = mat->stencil.dim;
5530: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5531: PetscInt *dims = mat->stencil.dims+1;
5532: PetscInt *starts = mat->stencil.starts;
5533: PetscInt *dxm = (PetscInt*) rows;
5534: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5542: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5543: for (i = 0; i < numRows; ++i) {
5544: /* Skip unused dimensions (they are ordered k, j, i, c) */
5545: for (j = 0; j < 3-sdim; ++j) dxm++;
5546: /* Local index in X dir */
5547: tmp = *dxm++ - starts[0];
5548: /* Loop over remaining dimensions */
5549: for (j = 0; j < dim-1; ++j) {
5550: /* If nonlocal, set index to be negative */
5551: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5552: /* Update local index */
5553: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5554: }
5555: /* Skip component slot if necessary */
5556: if (mat->stencil.noc) dxm++;
5557: /* Local row number */
5558: if (tmp >= 0) {
5559: jdxm[numNewRows++] = tmp;
5560: }
5561: }
5562: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5563: PetscFree(jdxm);
5564: return(0);
5565: }
5569: /*@C
5570: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5571: of a set of rows and columns of a matrix.
5573: Collective on Mat
5575: Input Parameters:
5576: + mat - the matrix
5577: . numRows - the number of rows/columns to remove
5578: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5579: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5580: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5581: - b - optional vector of right hand side, that will be adjusted by provided solution
5583: Notes:
5584: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5585: but does not release memory. For the dense and block diagonal
5586: formats this does not alter the nonzero structure.
5588: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5589: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5590: merely zeroed.
5592: The user can set a value in the diagonal entry (or for the AIJ and
5593: row formats can optionally remove the main diagonal entry from the
5594: nonzero structure as well, by passing 0.0 as the final argument).
5596: For the parallel case, all processes that share the matrix (i.e.,
5597: those in the communicator used for matrix creation) MUST call this
5598: routine, regardless of whether any rows being zeroed are owned by
5599: them.
5601: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5602: list only rows local to itself, but the row/column numbers are given in local numbering).
5604: The grid coordinates are across the entire grid, not just the local portion
5606: In Fortran idxm and idxn should be declared as
5607: $ MatStencil idxm(4,m)
5608: and the values inserted using
5609: $ idxm(MatStencil_i,1) = i
5610: $ idxm(MatStencil_j,1) = j
5611: $ idxm(MatStencil_k,1) = k
5612: $ idxm(MatStencil_c,1) = c
5613: etc
5615: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5616: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5617: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5618: DMDA_BOUNDARY_PERIODIC boundary type.
5620: 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
5621: a single value per point) you can skip filling those indices.
5623: Level: intermediate
5625: Concepts: matrices^zeroing rows
5627: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5628: @*/
5629: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5630: {
5631: PetscInt dim = mat->stencil.dim;
5632: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5633: PetscInt *dims = mat->stencil.dims+1;
5634: PetscInt *starts = mat->stencil.starts;
5635: PetscInt *dxm = (PetscInt*) rows;
5636: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5644: PetscMalloc(numRows*sizeof(PetscInt), &jdxm);
5645: for (i = 0; i < numRows; ++i) {
5646: /* Skip unused dimensions (they are ordered k, j, i, c) */
5647: for (j = 0; j < 3-sdim; ++j) dxm++;
5648: /* Local index in X dir */
5649: tmp = *dxm++ - starts[0];
5650: /* Loop over remaining dimensions */
5651: for (j = 0; j < dim-1; ++j) {
5652: /* If nonlocal, set index to be negative */
5653: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5654: /* Update local index */
5655: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5656: }
5657: /* Skip component slot if necessary */
5658: if (mat->stencil.noc) dxm++;
5659: /* Local row number */
5660: if (tmp >= 0) {
5661: jdxm[numNewRows++] = tmp;
5662: }
5663: }
5664: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
5665: PetscFree(jdxm);
5666: return(0);
5667: }
5671: /*@C
5672: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
5673: of a set of rows of a matrix; using local numbering of rows.
5675: Collective on Mat
5677: Input Parameters:
5678: + mat - the matrix
5679: . numRows - the number of rows to remove
5680: . rows - the global row indices
5681: . diag - value put in all diagonals of eliminated rows
5682: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5683: - b - optional vector of right hand side, that will be adjusted by provided solution
5685: Notes:
5686: Before calling MatZeroRowsLocal(), the user must first set the
5687: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5689: For the AIJ matrix formats this removes the old nonzero structure,
5690: but does not release memory. For the dense and block diagonal
5691: formats this does not alter the nonzero structure.
5693: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5694: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5695: merely zeroed.
5697: The user can set a value in the diagonal entry (or for the AIJ and
5698: row formats can optionally remove the main diagonal entry from the
5699: nonzero structure as well, by passing 0.0 as the final argument).
5701: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5702: owns that are to be zeroed. This saves a global synchronization in the implementation.
5704: Level: intermediate
5706: Concepts: matrices^zeroing
5708: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5709: @*/
5710: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5711: {
5718: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5719: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5720: MatCheckPreallocated(mat,1);
5722: if (mat->ops->zerorowslocal) {
5723: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5724: } else {
5725: IS is, newis;
5726: const PetscInt *newRows;
5728: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5729: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5730: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5731: ISGetIndices(newis,&newRows);
5732: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5733: ISRestoreIndices(newis,&newRows);
5734: ISDestroy(&newis);
5735: ISDestroy(&is);
5736: }
5737: PetscObjectStateIncrease((PetscObject)mat);
5738: #if defined(PETSC_HAVE_CUSP)
5739: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5740: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5741: }
5742: #endif
5743: return(0);
5744: }
5748: /*@C
5749: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5750: of a set of rows of a matrix; using local numbering of rows.
5752: Collective on Mat
5754: Input Parameters:
5755: + mat - the matrix
5756: . is - index set of rows to remove
5757: . diag - value put in all diagonals of eliminated rows
5758: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5759: - b - optional vector of right hand side, that will be adjusted by provided solution
5761: Notes:
5762: Before calling MatZeroRowsLocalIS(), the user must first set the
5763: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5765: For the AIJ matrix formats this removes the old nonzero structure,
5766: but does not release memory. For the dense and block diagonal
5767: formats this does not alter the nonzero structure.
5769: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5770: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5771: merely zeroed.
5773: The user can set a value in the diagonal entry (or for the AIJ and
5774: row formats can optionally remove the main diagonal entry from the
5775: nonzero structure as well, by passing 0.0 as the final argument).
5777: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5778: owns that are to be zeroed. This saves a global synchronization in the implementation.
5780: Level: intermediate
5782: Concepts: matrices^zeroing
5784: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5785: @*/
5786: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5787: {
5789: PetscInt numRows;
5790: const PetscInt *rows;
5796: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5797: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5798: MatCheckPreallocated(mat,1);
5800: ISGetLocalSize(is,&numRows);
5801: ISGetIndices(is,&rows);
5802: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5803: ISRestoreIndices(is,&rows);
5804: return(0);
5805: }
5809: /*@C
5810: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5811: of a set of rows and columns of a matrix; using local numbering of rows.
5813: Collective on Mat
5815: Input Parameters:
5816: + mat - the matrix
5817: . numRows - the number of rows to remove
5818: . rows - the global row indices
5819: . diag - value put in all diagonals of eliminated rows
5820: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5821: - b - optional vector of right hand side, that will be adjusted by provided solution
5823: Notes:
5824: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5825: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5827: The user can set a value in the diagonal entry (or for the AIJ and
5828: row formats can optionally remove the main diagonal entry from the
5829: nonzero structure as well, by passing 0.0 as the final argument).
5831: Level: intermediate
5833: Concepts: matrices^zeroing
5835: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5836: @*/
5837: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5838: {
5840: IS is, newis;
5841: const PetscInt *newRows;
5847: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5848: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5849: MatCheckPreallocated(mat,1);
5851: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5852: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5853: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5854: ISGetIndices(newis,&newRows);
5855: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5856: ISRestoreIndices(newis,&newRows);
5857: ISDestroy(&newis);
5858: ISDestroy(&is);
5859: PetscObjectStateIncrease((PetscObject)mat);
5860: #if defined(PETSC_HAVE_CUSP)
5861: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5862: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5863: }
5864: #endif
5865: return(0);
5866: }
5870: /*@C
5871: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5872: of a set of rows and columns of a matrix; using local numbering of rows.
5874: Collective on Mat
5876: Input Parameters:
5877: + mat - the matrix
5878: . is - index set of rows to remove
5879: . diag - value put in all diagonals of eliminated rows
5880: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5881: - b - optional vector of right hand side, that will be adjusted by provided solution
5883: Notes:
5884: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5885: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5887: The user can set a value in the diagonal entry (or for the AIJ and
5888: row formats can optionally remove the main diagonal entry from the
5889: nonzero structure as well, by passing 0.0 as the final argument).
5891: Level: intermediate
5893: Concepts: matrices^zeroing
5895: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5896: @*/
5897: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5898: {
5900: PetscInt numRows;
5901: const PetscInt *rows;
5907: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5908: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5909: MatCheckPreallocated(mat,1);
5911: ISGetLocalSize(is,&numRows);
5912: ISGetIndices(is,&rows);
5913: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5914: ISRestoreIndices(is,&rows);
5915: return(0);
5916: }
5920: /*@
5921: MatGetSize - Returns the numbers of rows and columns in a matrix.
5923: Not Collective
5925: Input Parameter:
5926: . mat - the matrix
5928: Output Parameters:
5929: + m - the number of global rows
5930: - n - the number of global columns
5932: Note: both output parameters can be NULL on input.
5934: Level: beginner
5936: Concepts: matrices^size
5938: .seealso: MatGetLocalSize()
5939: @*/
5940: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5941: {
5944: if (m) *m = mat->rmap->N;
5945: if (n) *n = mat->cmap->N;
5946: return(0);
5947: }
5951: /*@
5952: MatGetLocalSize - Returns the number of rows and columns in a matrix
5953: stored locally. This information may be implementation dependent, so
5954: use with care.
5956: Not Collective
5958: Input Parameters:
5959: . mat - the matrix
5961: Output Parameters:
5962: + m - the number of local rows
5963: - n - the number of local columns
5965: Note: both output parameters can be NULL on input.
5967: Level: beginner
5969: Concepts: matrices^local size
5971: .seealso: MatGetSize()
5972: @*/
5973: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5974: {
5979: if (m) *m = mat->rmap->n;
5980: if (n) *n = mat->cmap->n;
5981: return(0);
5982: }
5986: /*@
5987: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5988: this processor. (The columns of the "diagonal block")
5990: Not Collective, unless matrix has not been allocated, then collective on Mat
5992: Input Parameters:
5993: . mat - the matrix
5995: Output Parameters:
5996: + m - the global index of the first local column
5997: - n - one more than the global index of the last local column
5999: Notes: both output parameters can be NULL on input.
6001: Level: developer
6003: Concepts: matrices^column ownership
6005: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6007: @*/
6008: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6009: {
6015: MatCheckPreallocated(mat,1);
6016: if (m) *m = mat->cmap->rstart;
6017: if (n) *n = mat->cmap->rend;
6018: return(0);
6019: }
6023: /*@
6024: MatGetOwnershipRange - Returns the range of matrix rows owned by
6025: this processor, assuming that the matrix is laid out with the first
6026: n1 rows on the first processor, the next n2 rows on the second, etc.
6027: For certain parallel layouts this range may not be well defined.
6029: Not Collective
6031: Input Parameters:
6032: . mat - the matrix
6034: Output Parameters:
6035: + m - the global index of the first local row
6036: - n - one more than the global index of the last local row
6038: Note: Both output parameters can be NULL on input.
6039: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6040: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6041: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6043: Level: beginner
6045: Concepts: matrices^row ownership
6047: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6049: @*/
6050: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6051: {
6057: MatCheckPreallocated(mat,1);
6058: if (m) *m = mat->rmap->rstart;
6059: if (n) *n = mat->rmap->rend;
6060: return(0);
6061: }
6065: /*@C
6066: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6067: each process
6069: Not Collective, unless matrix has not been allocated, then collective on Mat
6071: Input Parameters:
6072: . mat - the matrix
6074: Output Parameters:
6075: . ranges - start of each processors portion plus one more then the total length at the end
6077: Level: beginner
6079: Concepts: matrices^row ownership
6081: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6083: @*/
6084: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6085: {
6091: MatCheckPreallocated(mat,1);
6092: PetscLayoutGetRanges(mat->rmap,ranges);
6093: return(0);
6094: }
6098: /*@C
6099: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6100: this processor. (The columns of the "diagonal blocks" for each process)
6102: Not Collective, unless matrix has not been allocated, then collective on Mat
6104: Input Parameters:
6105: . mat - the matrix
6107: Output Parameters:
6108: . ranges - start of each processors portion plus one more then the total length at the end
6110: Level: beginner
6112: Concepts: matrices^column ownership
6114: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6116: @*/
6117: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6118: {
6124: MatCheckPreallocated(mat,1);
6125: PetscLayoutGetRanges(mat->cmap,ranges);
6126: return(0);
6127: }
6131: /*@C
6132: MatGetOwnershipIS - Get row and column ownership as index sets
6134: Not Collective
6136: Input Arguments:
6137: . A - matrix of type Elemental
6139: Output Arguments:
6140: + rows - rows in which this process owns elements
6141: . cols - columns in which this process owns elements
6143: Level: intermediate
6145: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6146: @*/
6147: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6148: {
6149: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6152: MatCheckPreallocated(A,1);
6153: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6154: if (f) {
6155: (*f)(A,rows,cols);
6156: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6157: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6158: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6159: }
6160: return(0);
6161: }
6165: /*@C
6166: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6167: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6168: to complete the factorization.
6170: Collective on Mat
6172: Input Parameters:
6173: + mat - the matrix
6174: . row - row permutation
6175: . column - column permutation
6176: - info - structure containing
6177: $ levels - number of levels of fill.
6178: $ expected fill - as ratio of original fill.
6179: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6180: missing diagonal entries)
6182: Output Parameters:
6183: . fact - new matrix that has been symbolically factored
6185: Notes:
6186: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6187: choosing the fill factor for better efficiency.
6189: Most users should employ the simplified KSP interface for linear solvers
6190: instead of working directly with matrix algebra routines such as this.
6191: See, e.g., KSPCreate().
6193: Level: developer
6195: Concepts: matrices^symbolic LU factorization
6196: Concepts: matrices^factorization
6197: Concepts: LU^symbolic factorization
6199: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6200: MatGetOrdering(), MatFactorInfo
6202: Developer Note: fortran interface is not autogenerated as the f90
6203: interface defintion cannot be generated correctly [due to MatFactorInfo]
6205: @*/
6206: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6207: {
6217: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6218: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6219: if (!(fact)->ops->ilufactorsymbolic) {
6220: const MatSolverPackage spackage;
6221: MatFactorGetSolverPackage(fact,&spackage);
6222: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6223: }
6224: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6225: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6226: MatCheckPreallocated(mat,2);
6228: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6229: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6230: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6231: return(0);
6232: }
6236: /*@C
6237: MatICCFactorSymbolic - Performs symbolic incomplete
6238: Cholesky factorization for a symmetric matrix. Use
6239: MatCholeskyFactorNumeric() to complete the factorization.
6241: Collective on Mat
6243: Input Parameters:
6244: + mat - the matrix
6245: . perm - row and column permutation
6246: - info - structure containing
6247: $ levels - number of levels of fill.
6248: $ expected fill - as ratio of original fill.
6250: Output Parameter:
6251: . fact - the factored matrix
6253: Notes:
6254: Most users should employ the KSP interface for linear solvers
6255: instead of working directly with matrix algebra routines such as this.
6256: See, e.g., KSPCreate().
6258: Level: developer
6260: Concepts: matrices^symbolic incomplete Cholesky factorization
6261: Concepts: matrices^factorization
6262: Concepts: Cholsky^symbolic factorization
6264: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6266: Developer Note: fortran interface is not autogenerated as the f90
6267: interface defintion cannot be generated correctly [due to MatFactorInfo]
6269: @*/
6270: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6271: {
6280: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6281: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6282: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6283: if (!(fact)->ops->iccfactorsymbolic) {
6284: const MatSolverPackage spackage;
6285: MatFactorGetSolverPackage(fact,&spackage);
6286: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6287: }
6288: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6289: MatCheckPreallocated(mat,2);
6291: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6292: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6293: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6294: return(0);
6295: }
6299: /*@C
6300: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6301: points to an array of valid matrices, they may be reused to store the new
6302: submatrices.
6304: Collective on Mat
6306: Input Parameters:
6307: + mat - the matrix
6308: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6309: . irow, icol - index sets of rows and columns to extract (must be sorted)
6310: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6312: Output Parameter:
6313: . submat - the array of submatrices
6315: Notes:
6316: MatGetSubMatrices() can extract ONLY sequential submatrices
6317: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6318: to extract a parallel submatrix.
6320: Currently both row and column indices must be sorted to guarantee
6321: correctness with all matrix types.
6323: When extracting submatrices from a parallel matrix, each processor can
6324: form a different submatrix by setting the rows and columns of its
6325: individual index sets according to the local submatrix desired.
6327: When finished using the submatrices, the user should destroy
6328: them with MatDestroyMatrices().
6330: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6331: original matrix has not changed from that last call to MatGetSubMatrices().
6333: This routine creates the matrices in submat; you should NOT create them before
6334: calling it. It also allocates the array of matrix pointers submat.
6336: For BAIJ matrices the index sets must respect the block structure, that is if they
6337: request one row/column in a block, they must request all rows/columns that are in
6338: that block. For example, if the block size is 2 you cannot request just row 0 and
6339: column 0.
6341: Fortran Note:
6342: The Fortran interface is slightly different from that given below; it
6343: requires one to pass in as submat a Mat (integer) array of size at least m.
6345: Level: advanced
6347: Concepts: matrices^accessing submatrices
6348: Concepts: submatrices
6350: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6351: @*/
6352: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6353: {
6355: PetscInt i;
6356: PetscBool eq;
6361: if (n) {
6366: }
6368: if (n && scall == MAT_REUSE_MATRIX) {
6371: }
6372: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6373: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6374: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6375: MatCheckPreallocated(mat,1);
6377: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6378: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6379: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6380: for (i=0; i<n; i++) {
6381: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6382: ISEqual(irow[i],icol[i],&eq);
6383: if (eq) {
6384: if (mat->symmetric) {
6385: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6386: } else if (mat->hermitian) {
6387: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6388: } else if (mat->structurally_symmetric) {
6389: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6390: }
6391: }
6392: }
6393: }
6394: return(0);
6395: }
6399: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6400: {
6402: PetscInt i;
6403: PetscBool eq;
6408: if (n) {
6413: }
6415: if (n && scall == MAT_REUSE_MATRIX) {
6418: }
6419: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6420: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6421: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6422: MatCheckPreallocated(mat,1);
6424: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6425: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6426: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6427: for (i=0; i<n; i++) {
6428: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6429: ISEqual(irow[i],icol[i],&eq);
6430: if (eq) {
6431: if (mat->symmetric) {
6432: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6433: } else if (mat->hermitian) {
6434: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6435: } else if (mat->structurally_symmetric) {
6436: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6437: }
6438: }
6439: }
6440: }
6441: return(0);
6442: }
6446: /*@C
6447: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6449: Collective on Mat
6451: Input Parameters:
6452: + n - the number of local matrices
6453: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6454: sequence of MatGetSubMatrices())
6456: Level: advanced
6458: Notes: Frees not only the matrices, but also the array that contains the matrices
6459: In Fortran will not free the array.
6461: .seealso: MatGetSubMatrices()
6462: @*/
6463: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6464: {
6466: PetscInt i;
6469: if (!*mat) return(0);
6470: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6472: for (i=0; i<n; i++) {
6473: MatDestroy(&(*mat)[i]);
6474: }
6475: /* memory is allocated even if n = 0 */
6476: PetscFree(*mat);
6477: *mat = NULL;
6478: return(0);
6479: }
6483: /*@C
6484: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6486: Collective on Mat
6488: Input Parameters:
6489: . mat - the matrix
6491: Output Parameter:
6492: . matstruct - the sequential matrix with the nonzero structure of mat
6494: Level: intermediate
6496: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6497: @*/
6498: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6499: {
6507: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6508: MatCheckPreallocated(mat,1);
6510: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6511: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6512: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6513: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6514: return(0);
6515: }
6519: /*@C
6520: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6522: Collective on Mat
6524: Input Parameters:
6525: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6526: sequence of MatGetSequentialNonzeroStructure())
6528: Level: advanced
6530: Notes: Frees not only the matrices, but also the array that contains the matrices
6532: .seealso: MatGetSeqNonzeroStructure()
6533: @*/
6534: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6535: {
6540: MatDestroy(mat);
6541: return(0);
6542: }
6546: /*@
6547: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6548: replaces the index sets by larger ones that represent submatrices with
6549: additional overlap.
6551: Collective on Mat
6553: Input Parameters:
6554: + mat - the matrix
6555: . n - the number of index sets
6556: . is - the array of index sets (these index sets will changed during the call)
6557: - ov - the additional overlap requested
6559: Level: developer
6561: Concepts: overlap
6562: Concepts: ASM^computing overlap
6564: .seealso: MatGetSubMatrices()
6565: @*/
6566: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6567: {
6573: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6574: if (n) {
6577: }
6578: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6579: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6580: MatCheckPreallocated(mat,1);
6582: if (!ov) return(0);
6583: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6584: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6585: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6586: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6587: return(0);
6588: }
6592: /*@
6593: MatGetBlockSize - Returns the matrix block size; useful especially for the
6594: block row and block diagonal formats.
6596: Not Collective
6598: Input Parameter:
6599: . mat - the matrix
6601: Output Parameter:
6602: . bs - block size
6604: Notes:
6605: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6607: Level: intermediate
6609: Concepts: matrices^block size
6611: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6612: @*/
6613: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6614: {
6619: MatCheckPreallocated(mat,1);
6620: *bs = mat->rmap->bs;
6621: return(0);
6622: }
6626: /*@
6627: MatGetBlockSizes - Returns the matrix block row and column sizes;
6628: useful especially for the block row and block diagonal formats.
6630: Not Collective
6632: Input Parameter:
6633: . mat - the matrix
6635: Output Parameter:
6636: . rbs - row block size
6637: . cbs - coumn block size
6639: Notes:
6640: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6642: Level: intermediate
6644: Concepts: matrices^block size
6646: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6647: @*/
6648: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6649: {
6655: MatCheckPreallocated(mat,1);
6656: if (rbs) *rbs = mat->rmap->bs;
6657: if (cbs) *cbs = mat->cmap->bs;
6658: return(0);
6659: }
6663: /*@
6664: MatSetBlockSize - Sets the matrix block size.
6666: Logically Collective on Mat
6668: Input Parameters:
6669: + mat - the matrix
6670: - bs - block size
6672: Notes:
6673: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6675: Level: intermediate
6677: Concepts: matrices^block size
6679: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6680: @*/
6681: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6682: {
6688: PetscLayoutSetBlockSize(mat->rmap,bs);
6689: PetscLayoutSetBlockSize(mat->cmap,bs);
6690: return(0);
6691: }
6695: /*@
6696: MatSetBlockSizes - Sets the matrix block row and column sizes.
6698: Logically Collective on Mat
6700: Input Parameters:
6701: + mat - the matrix
6702: - rbs - row block size
6703: - cbs - column block size
6705: Notes:
6706: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6708: Level: intermediate
6710: Concepts: matrices^block size
6712: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6713: @*/
6714: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6715: {
6722: PetscLayoutSetBlockSize(mat->rmap,rbs);
6723: PetscLayoutSetBlockSize(mat->cmap,cbs);
6724: return(0);
6725: }
6729: /*@C
6730: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6732: Collective on Mat
6734: Input Parameters:
6735: + mat - the matrix
6736: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6737: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6738: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6739: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6740: always used.
6742: Output Parameters:
6743: + n - number of rows in the (possibly compressed) matrix
6744: . ia - the row pointers [of length n+1]
6745: . ja - the column indices
6746: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6747: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6749: Level: developer
6751: Notes: You CANNOT change any of the ia[] or ja[] values.
6753: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6755: Fortran Node
6757: In Fortran use
6758: $ PetscInt ia(1), ja(1)
6759: $ PetscOffset iia, jja
6760: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6761: $
6762: $ or
6763: $
6764: $ PetscScalar, pointer :: xx_v(:)
6765: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6768: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6770: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6771: @*/
6772: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6773: {
6783: MatCheckPreallocated(mat,1);
6784: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6785: else {
6786: *done = PETSC_TRUE;
6787: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6788: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6789: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6790: }
6791: return(0);
6792: }
6796: /*@C
6797: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6799: Collective on Mat
6801: Input Parameters:
6802: + mat - the matrix
6803: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6804: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6805: symmetrized
6806: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6807: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6808: always used.
6810: Output Parameters:
6811: + n - number of columns in the (possibly compressed) matrix
6812: . ia - the column pointers
6813: . ja - the row indices
6814: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6816: Level: developer
6818: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6819: @*/
6820: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6821: {
6831: MatCheckPreallocated(mat,1);
6832: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6833: else {
6834: *done = PETSC_TRUE;
6835: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6836: }
6837: return(0);
6838: }
6842: /*@C
6843: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6844: MatGetRowIJ().
6846: Collective on Mat
6848: Input Parameters:
6849: + mat - the matrix
6850: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6851: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6852: symmetrized
6853: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6854: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6855: always used.
6857: Output Parameters:
6858: + n - size of (possibly compressed) matrix
6859: . ia - the row pointers
6860: . ja - the column indices
6861: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6863: Level: developer
6865: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6866: @*/
6867: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6868: {
6877: MatCheckPreallocated(mat,1);
6879: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6880: else {
6881: *done = PETSC_TRUE;
6882: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6883: if (n) *n = 0;
6884: if (ia) *ia = NULL;
6885: if (ja) *ja = NULL;
6886: }
6887: return(0);
6888: }
6892: /*@C
6893: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6894: MatGetColumnIJ().
6896: Collective on Mat
6898: Input Parameters:
6899: + mat - the matrix
6900: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6901: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6902: symmetrized
6903: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6904: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6905: always used.
6907: Output Parameters:
6908: + n - size of (possibly compressed) matrix
6909: . ia - the column pointers
6910: . ja - the row indices
6911: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6913: Level: developer
6915: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6916: @*/
6917: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6918: {
6927: MatCheckPreallocated(mat,1);
6929: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6930: else {
6931: *done = PETSC_TRUE;
6932: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6933: if (n) *n = 0;
6934: if (ia) *ia = NULL;
6935: if (ja) *ja = NULL;
6936: }
6937: return(0);
6938: }
6942: /*@C
6943: MatColoringPatch -Used inside matrix coloring routines that
6944: use MatGetRowIJ() and/or MatGetColumnIJ().
6946: Collective on Mat
6948: Input Parameters:
6949: + mat - the matrix
6950: . ncolors - max color value
6951: . n - number of entries in colorarray
6952: - colorarray - array indicating color for each column
6954: Output Parameters:
6955: . iscoloring - coloring generated using colorarray information
6957: Level: developer
6959: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6961: @*/
6962: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6963: {
6971: MatCheckPreallocated(mat,1);
6973: if (!mat->ops->coloringpatch) {
6974: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
6975: } else {
6976: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6977: }
6978: return(0);
6979: }
6984: /*@
6985: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6987: Logically Collective on Mat
6989: Input Parameter:
6990: . mat - the factored matrix to be reset
6992: Notes:
6993: This routine should be used only with factored matrices formed by in-place
6994: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
6995: format). This option can save memory, for example, when solving nonlinear
6996: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
6997: ILU(0) preconditioner.
6999: Note that one can specify in-place ILU(0) factorization by calling
7000: .vb
7001: PCType(pc,PCILU);
7002: PCFactorSeUseInPlace(pc);
7003: .ve
7004: or by using the options -pc_type ilu -pc_factor_in_place
7006: In-place factorization ILU(0) can also be used as a local
7007: solver for the blocks within the block Jacobi or additive Schwarz
7008: methods (runtime option: -sub_pc_factor_in_place). See the discussion
7009: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7010: local solver options.
7012: Most users should employ the simplified KSP interface for linear solvers
7013: instead of working directly with matrix algebra routines such as this.
7014: See, e.g., KSPCreate().
7016: Level: developer
7018: .seealso: PCFactorSetUseInPlace()
7020: Concepts: matrices^unfactored
7022: @*/
7023: PetscErrorCode MatSetUnfactored(Mat mat)
7024: {
7030: MatCheckPreallocated(mat,1);
7031: mat->factortype = MAT_FACTOR_NONE;
7032: if (!mat->ops->setunfactored) return(0);
7033: (*mat->ops->setunfactored)(mat);
7034: return(0);
7035: }
7037: /*MC
7038: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7040: Synopsis:
7041: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7043: Not collective
7045: Input Parameter:
7046: . x - matrix
7048: Output Parameters:
7049: + xx_v - the Fortran90 pointer to the array
7050: - ierr - error code
7052: Example of Usage:
7053: .vb
7054: PetscScalar, pointer xx_v(:,:)
7055: ....
7056: call MatDenseGetArrayF90(x,xx_v,ierr)
7057: a = xx_v(3)
7058: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7059: .ve
7061: Level: advanced
7063: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7065: Concepts: matrices^accessing array
7067: M*/
7069: /*MC
7070: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7071: accessed with MatDenseGetArrayF90().
7073: Synopsis:
7074: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7076: Not collective
7078: Input Parameters:
7079: + x - matrix
7080: - xx_v - the Fortran90 pointer to the array
7082: Output Parameter:
7083: . ierr - error code
7085: Example of Usage:
7086: .vb
7087: PetscScalar, pointer xx_v(:)
7088: ....
7089: call MatDenseGetArrayF90(x,xx_v,ierr)
7090: a = xx_v(3)
7091: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7092: .ve
7094: Level: advanced
7096: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7098: M*/
7101: /*MC
7102: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7104: Synopsis:
7105: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7107: Not collective
7109: Input Parameter:
7110: . x - matrix
7112: Output Parameters:
7113: + xx_v - the Fortran90 pointer to the array
7114: - ierr - error code
7116: Example of Usage:
7117: .vb
7118: PetscScalar, pointer xx_v(:,:)
7119: ....
7120: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7121: a = xx_v(3)
7122: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7123: .ve
7125: Level: advanced
7127: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7129: Concepts: matrices^accessing array
7131: M*/
7133: /*MC
7134: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7135: accessed with MatSeqAIJGetArrayF90().
7137: Synopsis:
7138: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7140: Not collective
7142: Input Parameters:
7143: + x - matrix
7144: - xx_v - the Fortran90 pointer to the array
7146: Output Parameter:
7147: . ierr - error code
7149: Example of Usage:
7150: .vb
7151: PetscScalar, pointer xx_v(:)
7152: ....
7153: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7154: a = xx_v(3)
7155: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7156: .ve
7158: Level: advanced
7160: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7162: M*/
7167: /*@
7168: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7169: as the original matrix.
7171: Collective on Mat
7173: Input Parameters:
7174: + mat - the original matrix
7175: . isrow - parallel IS containing the rows this processor should obtain
7176: . 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.
7177: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7179: Output Parameter:
7180: . newmat - the new submatrix, of the same type as the old
7182: Level: advanced
7184: Notes:
7185: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7187: The rows in isrow will be sorted into the same order as the original matrix on each process.
7189: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7190: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7191: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7192: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7193: you are finished using it.
7195: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7196: the input matrix.
7198: If iscol is NULL then all columns are obtained (not supported in Fortran).
7200: Example usage:
7201: Consider the following 8x8 matrix with 34 non-zero values, that is
7202: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7203: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7204: as follows:
7206: .vb
7207: 1 2 0 | 0 3 0 | 0 4
7208: Proc0 0 5 6 | 7 0 0 | 8 0
7209: 9 0 10 | 11 0 0 | 12 0
7210: -------------------------------------
7211: 13 0 14 | 15 16 17 | 0 0
7212: Proc1 0 18 0 | 19 20 21 | 0 0
7213: 0 0 0 | 22 23 0 | 24 0
7214: -------------------------------------
7215: Proc2 25 26 27 | 0 0 28 | 29 0
7216: 30 0 0 | 31 32 33 | 0 34
7217: .ve
7219: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7221: .vb
7222: 2 0 | 0 3 0 | 0
7223: Proc0 5 6 | 7 0 0 | 8
7224: -------------------------------
7225: Proc1 18 0 | 19 20 21 | 0
7226: -------------------------------
7227: Proc2 26 27 | 0 0 28 | 29
7228: 0 0 | 31 32 33 | 0
7229: .ve
7232: Concepts: matrices^submatrices
7234: .seealso: MatGetSubMatrices()
7235: @*/
7236: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7237: {
7239: PetscMPIInt size;
7240: Mat *local;
7241: IS iscoltmp;
7250: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7251: MatCheckPreallocated(mat,1);
7252: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7254: if (!iscol) {
7255: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7256: } else {
7257: iscoltmp = iscol;
7258: }
7260: /* if original matrix is on just one processor then use submatrix generated */
7261: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7262: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7263: if (!iscol) {ISDestroy(&iscoltmp);}
7264: return(0);
7265: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7266: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7267: *newmat = *local;
7268: PetscFree(local);
7269: if (!iscol) {ISDestroy(&iscoltmp);}
7270: return(0);
7271: } else if (!mat->ops->getsubmatrix) {
7272: /* Create a new matrix type that implements the operation using the full matrix */
7273: switch (cll) {
7274: case MAT_INITIAL_MATRIX:
7275: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7276: break;
7277: case MAT_REUSE_MATRIX:
7278: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7279: break;
7280: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7281: }
7282: if (!iscol) {ISDestroy(&iscoltmp);}
7283: return(0);
7284: }
7286: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7287: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7288: if (!iscol) {ISDestroy(&iscoltmp);}
7289: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7290: return(0);
7291: }
7295: /*@
7296: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7297: used during the assembly process to store values that belong to
7298: other processors.
7300: Not Collective
7302: Input Parameters:
7303: + mat - the matrix
7304: . size - the initial size of the stash.
7305: - bsize - the initial size of the block-stash(if used).
7307: Options Database Keys:
7308: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7309: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7311: Level: intermediate
7313: Notes:
7314: The block-stash is used for values set with MatSetValuesBlocked() while
7315: the stash is used for values set with MatSetValues()
7317: Run with the option -info and look for output of the form
7318: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7319: to determine the appropriate value, MM, to use for size and
7320: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7321: to determine the value, BMM to use for bsize
7323: Concepts: stash^setting matrix size
7324: Concepts: matrices^stash
7326: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7328: @*/
7329: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7330: {
7336: MatStashSetInitialSize_Private(&mat->stash,size);
7337: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7338: return(0);
7339: }
7343: /*@
7344: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7345: the matrix
7347: Neighbor-wise Collective on Mat
7349: Input Parameters:
7350: + mat - the matrix
7351: . x,y - the vectors
7352: - w - where the result is stored
7354: Level: intermediate
7356: Notes:
7357: w may be the same vector as y.
7359: This allows one to use either the restriction or interpolation (its transpose)
7360: matrix to do the interpolation
7362: Concepts: interpolation
7364: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7366: @*/
7367: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7368: {
7370: PetscInt M,N,Ny;
7378: MatCheckPreallocated(A,1);
7379: MatGetSize(A,&M,&N);
7380: VecGetSize(y,&Ny);
7381: if (M == Ny) {
7382: MatMultAdd(A,x,y,w);
7383: } else {
7384: MatMultTransposeAdd(A,x,y,w);
7385: }
7386: return(0);
7387: }
7391: /*@
7392: MatInterpolate - y = A*x or A'*x depending on the shape of
7393: the matrix
7395: Neighbor-wise Collective on Mat
7397: Input Parameters:
7398: + mat - the matrix
7399: - x,y - the vectors
7401: Level: intermediate
7403: Notes:
7404: This allows one to use either the restriction or interpolation (its transpose)
7405: matrix to do the interpolation
7407: Concepts: matrices^interpolation
7409: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7411: @*/
7412: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7413: {
7415: PetscInt M,N,Ny;
7422: MatCheckPreallocated(A,1);
7423: MatGetSize(A,&M,&N);
7424: VecGetSize(y,&Ny);
7425: if (M == Ny) {
7426: MatMult(A,x,y);
7427: } else {
7428: MatMultTranspose(A,x,y);
7429: }
7430: return(0);
7431: }
7435: /*@
7436: MatRestrict - y = A*x or A'*x
7438: Neighbor-wise Collective on Mat
7440: Input Parameters:
7441: + mat - the matrix
7442: - x,y - the vectors
7444: Level: intermediate
7446: Notes:
7447: This allows one to use either the restriction or interpolation (its transpose)
7448: matrix to do the restriction
7450: Concepts: matrices^restriction
7452: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7454: @*/
7455: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7456: {
7458: PetscInt M,N,Ny;
7465: MatCheckPreallocated(A,1);
7467: MatGetSize(A,&M,&N);
7468: VecGetSize(y,&Ny);
7469: if (M == Ny) {
7470: MatMult(A,x,y);
7471: } else {
7472: MatMultTranspose(A,x,y);
7473: }
7474: return(0);
7475: }
7479: /*@
7480: MatGetNullSpace - retrieves the null space to a matrix.
7482: Logically Collective on Mat and MatNullSpace
7484: Input Parameters:
7485: + mat - the matrix
7486: - nullsp - the null space object
7488: Level: developer
7490: Notes:
7491: This null space is used by solvers. Overwrites any previous null space that may have been attached
7493: Concepts: null space^attaching to matrix
7495: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7496: @*/
7497: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7498: {
7503: *nullsp = mat->nullsp;
7504: return(0);
7505: }
7509: /*@
7510: MatSetNullSpace - attaches a null space to a matrix.
7511: This null space will be removed from the resulting vector whenever
7512: MatMult() is called
7514: Logically Collective on Mat and MatNullSpace
7516: Input Parameters:
7517: + mat - the matrix
7518: - nullsp - the null space object
7520: Level: advanced
7522: Notes:
7523: This null space is used by solvers. Overwrites any previous null space that may have been attached
7525: Concepts: null space^attaching to matrix
7527: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7528: @*/
7529: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7530: {
7537: MatCheckPreallocated(mat,1);
7538: PetscObjectReference((PetscObject)nullsp);
7539: MatNullSpaceDestroy(&mat->nullsp);
7541: mat->nullsp = nullsp;
7542: return(0);
7543: }
7547: /*@
7548: MatSetNearNullSpace - attaches a null space to a matrix.
7549: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7551: Logically Collective on Mat and MatNullSpace
7553: Input Parameters:
7554: + mat - the matrix
7555: - nullsp - the null space object
7557: Level: advanced
7559: Notes:
7560: Overwrites any previous near null space that may have been attached
7562: Concepts: null space^attaching to matrix
7564: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7565: @*/
7566: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7567: {
7574: MatCheckPreallocated(mat,1);
7575: PetscObjectReference((PetscObject)nullsp);
7576: MatNullSpaceDestroy(&mat->nearnullsp);
7578: mat->nearnullsp = nullsp;
7579: return(0);
7580: }
7584: /*@
7585: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7587: Not Collective
7589: Input Parameters:
7590: . mat - the matrix
7592: Output Parameters:
7593: . nullsp - the null space object, NULL if not set
7595: Level: developer
7597: Concepts: null space^attaching to matrix
7599: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7600: @*/
7601: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7602: {
7607: MatCheckPreallocated(mat,1);
7608: *nullsp = mat->nearnullsp;
7609: return(0);
7610: }
7614: /*@C
7615: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7617: Collective on Mat
7619: Input Parameters:
7620: + mat - the matrix
7621: . row - row/column permutation
7622: . fill - expected fill factor >= 1.0
7623: - level - level of fill, for ICC(k)
7625: Notes:
7626: Probably really in-place only when level of fill is zero, otherwise allocates
7627: new space to store factored matrix and deletes previous memory.
7629: Most users should employ the simplified KSP interface for linear solvers
7630: instead of working directly with matrix algebra routines such as this.
7631: See, e.g., KSPCreate().
7633: Level: developer
7635: Concepts: matrices^incomplete Cholesky factorization
7636: Concepts: Cholesky factorization
7638: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7640: Developer Note: fortran interface is not autogenerated as the f90
7641: interface defintion cannot be generated correctly [due to MatFactorInfo]
7643: @*/
7644: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7645: {
7653: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7654: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7655: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7656: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7657: MatCheckPreallocated(mat,1);
7658: (*mat->ops->iccfactor)(mat,row,info);
7659: PetscObjectStateIncrease((PetscObject)mat);
7660: return(0);
7661: }
7665: /*@
7666: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7668: Not Collective
7670: Input Parameters:
7671: + mat - the matrix
7672: . nl - leading dimension of v
7673: - v - the values compute with ADIFOR
7675: Level: developer
7677: Notes:
7678: Must call MatSetColoring() before using this routine. Also this matrix must already
7679: have its nonzero pattern determined.
7681: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7682: MatSetValues(), MatSetColoring()
7683: @*/
7684: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7685: {
7693: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7694: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7695: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7696: (*mat->ops->setvaluesadifor)(mat,nl,v);
7697: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7698: PetscObjectStateIncrease((PetscObject)mat);
7699: return(0);
7700: }
7704: /*@
7705: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7706: ghosted ones.
7708: Not Collective
7710: Input Parameters:
7711: + mat - the matrix
7712: - diag = the diagonal values, including ghost ones
7714: Level: developer
7716: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7718: .seealso: MatDiagonalScale()
7719: @*/
7720: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7721: {
7723: PetscMPIInt size;
7730: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7731: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7732: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7733: if (size == 1) {
7734: PetscInt n,m;
7735: VecGetSize(diag,&n);
7736: MatGetSize(mat,0,&m);
7737: if (m == n) {
7738: MatDiagonalScale(mat,0,diag);
7739: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7740: } else {
7741: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7742: }
7743: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7744: PetscObjectStateIncrease((PetscObject)mat);
7745: return(0);
7746: }
7750: /*@
7751: MatGetInertia - Gets the inertia from a factored matrix
7753: Collective on Mat
7755: Input Parameter:
7756: . mat - the matrix
7758: Output Parameters:
7759: + nneg - number of negative eigenvalues
7760: . nzero - number of zero eigenvalues
7761: - npos - number of positive eigenvalues
7763: Level: advanced
7765: Notes: Matrix must have been factored by MatCholeskyFactor()
7768: @*/
7769: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7770: {
7776: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7777: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7778: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7779: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7780: return(0);
7781: }
7783: /* ----------------------------------------------------------------*/
7786: /*@C
7787: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7789: Neighbor-wise Collective on Mat and Vecs
7791: Input Parameters:
7792: + mat - the factored matrix
7793: - b - the right-hand-side vectors
7795: Output Parameter:
7796: . x - the result vectors
7798: Notes:
7799: The vectors b and x cannot be the same. I.e., one cannot
7800: call MatSolves(A,x,x).
7802: Notes:
7803: Most users should employ the simplified KSP interface for linear solvers
7804: instead of working directly with matrix algebra routines such as this.
7805: See, e.g., KSPCreate().
7807: Level: developer
7809: Concepts: matrices^triangular solves
7811: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7812: @*/
7813: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7814: {
7820: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7821: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7822: if (!mat->rmap->N && !mat->cmap->N) return(0);
7824: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7825: MatCheckPreallocated(mat,1);
7826: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7827: (*mat->ops->solves)(mat,b,x);
7828: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7829: return(0);
7830: }
7834: /*@
7835: MatIsSymmetric - Test whether a matrix is symmetric
7837: Collective on Mat
7839: Input Parameter:
7840: + A - the matrix to test
7841: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7843: Output Parameters:
7844: . flg - the result
7846: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7848: Level: intermediate
7850: Concepts: matrix^symmetry
7852: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7853: @*/
7854: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7855: {
7862: if (!A->symmetric_set) {
7863: if (!A->ops->issymmetric) {
7864: MatType mattype;
7865: MatGetType(A,&mattype);
7866: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7867: }
7868: (*A->ops->issymmetric)(A,tol,flg);
7869: if (!tol) {
7870: A->symmetric_set = PETSC_TRUE;
7871: A->symmetric = *flg;
7872: if (A->symmetric) {
7873: A->structurally_symmetric_set = PETSC_TRUE;
7874: A->structurally_symmetric = PETSC_TRUE;
7875: }
7876: }
7877: } else if (A->symmetric) {
7878: *flg = PETSC_TRUE;
7879: } else if (!tol) {
7880: *flg = PETSC_FALSE;
7881: } else {
7882: if (!A->ops->issymmetric) {
7883: MatType mattype;
7884: MatGetType(A,&mattype);
7885: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7886: }
7887: (*A->ops->issymmetric)(A,tol,flg);
7888: }
7889: return(0);
7890: }
7894: /*@
7895: MatIsHermitian - Test whether a matrix is Hermitian
7897: Collective on Mat
7899: Input Parameter:
7900: + A - the matrix to test
7901: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7903: Output Parameters:
7904: . flg - the result
7906: Level: intermediate
7908: Concepts: matrix^symmetry
7910: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7911: MatIsSymmetricKnown(), MatIsSymmetric()
7912: @*/
7913: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7914: {
7921: if (!A->hermitian_set) {
7922: if (!A->ops->ishermitian) {
7923: MatType mattype;
7924: MatGetType(A,&mattype);
7925: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7926: }
7927: (*A->ops->ishermitian)(A,tol,flg);
7928: if (!tol) {
7929: A->hermitian_set = PETSC_TRUE;
7930: A->hermitian = *flg;
7931: if (A->hermitian) {
7932: A->structurally_symmetric_set = PETSC_TRUE;
7933: A->structurally_symmetric = PETSC_TRUE;
7934: }
7935: }
7936: } else if (A->hermitian) {
7937: *flg = PETSC_TRUE;
7938: } else if (!tol) {
7939: *flg = PETSC_FALSE;
7940: } else {
7941: if (!A->ops->ishermitian) {
7942: MatType mattype;
7943: MatGetType(A,&mattype);
7944: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7945: }
7946: (*A->ops->ishermitian)(A,tol,flg);
7947: }
7948: return(0);
7949: }
7953: /*@
7954: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7956: Not Collective
7958: Input Parameter:
7959: . A - the matrix to check
7961: Output Parameters:
7962: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7963: - flg - the result
7965: Level: advanced
7967: Concepts: matrix^symmetry
7969: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7970: if you want it explicitly checked
7972: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7973: @*/
7974: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
7975: {
7980: if (A->symmetric_set) {
7981: *set = PETSC_TRUE;
7982: *flg = A->symmetric;
7983: } else {
7984: *set = PETSC_FALSE;
7985: }
7986: return(0);
7987: }
7991: /*@
7992: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
7994: Not Collective
7996: Input Parameter:
7997: . A - the matrix to check
7999: Output Parameters:
8000: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8001: - flg - the result
8003: Level: advanced
8005: Concepts: matrix^symmetry
8007: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8008: if you want it explicitly checked
8010: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8011: @*/
8012: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8013: {
8018: if (A->hermitian_set) {
8019: *set = PETSC_TRUE;
8020: *flg = A->hermitian;
8021: } else {
8022: *set = PETSC_FALSE;
8023: }
8024: return(0);
8025: }
8029: /*@
8030: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8032: Collective on Mat
8034: Input Parameter:
8035: . A - the matrix to test
8037: Output Parameters:
8038: . flg - the result
8040: Level: intermediate
8042: Concepts: matrix^symmetry
8044: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8045: @*/
8046: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8047: {
8053: if (!A->structurally_symmetric_set) {
8054: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8055: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8057: A->structurally_symmetric_set = PETSC_TRUE;
8058: }
8059: *flg = A->structurally_symmetric;
8060: return(0);
8061: }
8065: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8066: /*@
8067: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8068: to be communicated to other processors during the MatAssemblyBegin/End() process
8070: Not collective
8072: Input Parameter:
8073: . vec - the vector
8075: Output Parameters:
8076: + nstash - the size of the stash
8077: . reallocs - the number of additional mallocs incurred.
8078: . bnstash - the size of the block stash
8079: - breallocs - the number of additional mallocs incurred.in the block stash
8081: Level: advanced
8083: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8085: @*/
8086: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8087: {
8091: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8092: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8093: return(0);
8094: }
8098: /*@C
8099: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8100: parallel layout
8102: Collective on Mat
8104: Input Parameter:
8105: . mat - the matrix
8107: Output Parameter:
8108: + right - (optional) vector that the matrix can be multiplied against
8109: - left - (optional) vector that the matrix vector product can be stored in
8111: Level: advanced
8113: .seealso: MatCreate()
8114: @*/
8115: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8116: {
8122: MatCheckPreallocated(mat,1);
8123: if (mat->ops->getvecs) {
8124: (*mat->ops->getvecs)(mat,right,left);
8125: } else {
8126: PetscMPIInt size;
8127: MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8128: if (right) {
8129: VecCreate(PetscObjectComm((PetscObject)mat),right);
8130: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8131: VecSetBlockSize(*right,mat->rmap->bs);
8132: VecSetType(*right,VECSTANDARD);
8133: PetscLayoutReference(mat->cmap,&(*right)->map);
8134: }
8135: if (left) {
8136: VecCreate(PetscObjectComm((PetscObject)mat),left);
8137: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8138: VecSetBlockSize(*left,mat->rmap->bs);
8139: VecSetType(*left,VECSTANDARD);
8140: PetscLayoutReference(mat->rmap,&(*left)->map);
8141: }
8142: }
8143: return(0);
8144: }
8148: /*@C
8149: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8150: with default values.
8152: Not Collective
8154: Input Parameters:
8155: . info - the MatFactorInfo data structure
8158: Notes: The solvers are generally used through the KSP and PC objects, for example
8159: PCLU, PCILU, PCCHOLESKY, PCICC
8161: Level: developer
8163: .seealso: MatFactorInfo
8165: Developer Note: fortran interface is not autogenerated as the f90
8166: interface defintion cannot be generated correctly [due to MatFactorInfo]
8168: @*/
8170: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8171: {
8175: PetscMemzero(info,sizeof(MatFactorInfo));
8176: return(0);
8177: }
8181: /*@
8182: MatPtAP - Creates the matrix product C = P^T * A * P
8184: Neighbor-wise Collective on Mat
8186: Input Parameters:
8187: + A - the matrix
8188: . P - the projection matrix
8189: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8190: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8192: Output Parameters:
8193: . C - the product matrix
8195: Notes:
8196: C will be created and must be destroyed by the user with MatDestroy().
8198: This routine is currently only implemented for pairs of AIJ matrices and classes
8199: which inherit from AIJ.
8201: Level: intermediate
8203: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8204: @*/
8205: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8206: {
8208: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8209: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8210: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8211: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8214: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8215: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
8219: MatCheckPreallocated(A,1);
8220: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8221: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8224: MatCheckPreallocated(P,2);
8225: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8226: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8228: 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);
8229: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8231: if (scall == MAT_REUSE_MATRIX) {
8234: if (viatranspose || viamatmatmatmult) {
8235: Mat Pt;
8236: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8237: if (viamatmatmatmult) {
8238: MatMatMatMult(Pt,A,P,scall,fill,C);
8239: } else {
8240: Mat AP;
8241: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8242: MatMatMult(Pt,AP,scall,fill,C);
8243: MatDestroy(&AP);
8244: }
8245: MatDestroy(&Pt);
8246: } else {
8247: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8248: (*(*C)->ops->ptapnumeric)(A,P,*C);
8249: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8250: }
8251: return(0);
8252: }
8254: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8255: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8257: fA = A->ops->ptap;
8258: fP = P->ops->ptap;
8259: if (fP == fA) {
8260: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8261: ptap = fA;
8262: } else {
8263: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8264: char ptapname[256];
8265: PetscStrcpy(ptapname,"MatPtAP_");
8266: PetscStrcat(ptapname,((PetscObject)A)->type_name);
8267: PetscStrcat(ptapname,"_");
8268: PetscStrcat(ptapname,((PetscObject)P)->type_name);
8269: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8270: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8271: 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);
8272: }
8274: if (viatranspose || viamatmatmatmult) {
8275: Mat Pt;
8276: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8277: if (viamatmatmatmult) {
8278: MatMatMatMult(Pt,A,P,scall,fill,C);
8279: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8280: } else {
8281: Mat AP;
8282: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8283: MatMatMult(Pt,AP,scall,fill,C);
8284: MatDestroy(&AP);
8285: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8286: }
8287: MatDestroy(&Pt);
8288: } else {
8289: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8290: (*ptap)(A,P,scall,fill,C);
8291: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8292: }
8293: return(0);
8294: }
8298: /*@
8299: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8301: Neighbor-wise Collective on Mat
8303: Input Parameters:
8304: + A - the matrix
8305: - P - the projection matrix
8307: Output Parameters:
8308: . C - the product matrix
8310: Notes:
8311: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8312: the user using MatDeatroy().
8314: This routine is currently only implemented for pairs of AIJ matrices and classes
8315: which inherit from AIJ. C will be of type MATAIJ.
8317: Level: intermediate
8319: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8320: @*/
8321: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8322: {
8328: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8329: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8332: MatCheckPreallocated(P,2);
8333: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8334: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8337: MatCheckPreallocated(C,3);
8338: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8339: 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);
8340: 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);
8341: 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);
8342: 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);
8343: MatCheckPreallocated(A,1);
8345: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8346: (*C->ops->ptapnumeric)(A,P,C);
8347: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8348: return(0);
8349: }
8353: /*@
8354: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8356: Neighbor-wise Collective on Mat
8358: Input Parameters:
8359: + A - the matrix
8360: - P - the projection matrix
8362: Output Parameters:
8363: . C - the (i,j) structure of the product matrix
8365: Notes:
8366: C will be created and must be destroyed by the user with MatDestroy().
8368: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8369: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8370: this (i,j) structure by calling MatPtAPNumeric().
8372: Level: intermediate
8374: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8375: @*/
8376: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8377: {
8383: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8384: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8385: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8388: MatCheckPreallocated(P,2);
8389: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8390: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8393: 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);
8394: 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);
8395: MatCheckPreallocated(A,1);
8396: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8397: (*A->ops->ptapsymbolic)(A,P,fill,C);
8398: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8400: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8401: return(0);
8402: }
8406: /*@
8407: MatRARt - Creates the matrix product C = R * A * R^T
8409: Neighbor-wise Collective on Mat
8411: Input Parameters:
8412: + A - the matrix
8413: . R - the projection matrix
8414: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8415: - fill - expected fill as ratio of nnz(C)/nnz(A)
8417: Output Parameters:
8418: . C - the product matrix
8420: Notes:
8421: C will be created and must be destroyed by the user with MatDestroy().
8423: This routine is currently only implemented for pairs of AIJ matrices and classes
8424: which inherit from AIJ.
8426: Level: intermediate
8428: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8429: @*/
8430: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8431: {
8437: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8438: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8441: MatCheckPreallocated(R,2);
8442: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8443: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8445: 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);
8446: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8447: MatCheckPreallocated(A,1);
8449: if (!A->ops->rart) {
8450: MatType mattype;
8451: MatGetType(A,&mattype);
8452: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8453: }
8454: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8455: (*A->ops->rart)(A,R,scall,fill,C);
8456: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8457: return(0);
8458: }
8462: /*@
8463: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8465: Neighbor-wise Collective on Mat
8467: Input Parameters:
8468: + A - the matrix
8469: - R - the projection matrix
8471: Output Parameters:
8472: . C - the product matrix
8474: Notes:
8475: C must have been created by calling MatRARtSymbolic and must be destroyed by
8476: the user using MatDeatroy().
8478: This routine is currently only implemented for pairs of AIJ matrices and classes
8479: which inherit from AIJ. C will be of type MATAIJ.
8481: Level: intermediate
8483: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8484: @*/
8485: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8486: {
8492: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8493: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8496: MatCheckPreallocated(R,2);
8497: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8498: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8501: MatCheckPreallocated(C,3);
8502: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8503: 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);
8504: 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);
8505: 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);
8506: 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);
8507: MatCheckPreallocated(A,1);
8509: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8510: (*A->ops->rartnumeric)(A,R,C);
8511: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8512: return(0);
8513: }
8517: /*@
8518: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8520: Neighbor-wise Collective on Mat
8522: Input Parameters:
8523: + A - the matrix
8524: - R - the projection matrix
8526: Output Parameters:
8527: . C - the (i,j) structure of the product matrix
8529: Notes:
8530: C will be created and must be destroyed by the user with MatDestroy().
8532: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8533: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8534: this (i,j) structure by calling MatRARtNumeric().
8536: Level: intermediate
8538: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8539: @*/
8540: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8541: {
8547: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8548: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8549: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8552: MatCheckPreallocated(R,2);
8553: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8554: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8557: 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);
8558: 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);
8559: MatCheckPreallocated(A,1);
8560: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8561: (*A->ops->rartsymbolic)(A,R,fill,C);
8562: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8564: MatSetBlockSize(*C,A->rmap->bs);
8565: return(0);
8566: }
8570: /*@
8571: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8573: Neighbor-wise Collective on Mat
8575: Input Parameters:
8576: + A - the left matrix
8577: . B - the right matrix
8578: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8579: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8580: if the result is a dense matrix this is irrelevent
8582: Output Parameters:
8583: . C - the product matrix
8585: Notes:
8586: Unless scall is MAT_REUSE_MATRIX C will be created.
8588: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8590: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8591: actually needed.
8593: If you have many matrices with the same non-zero structure to multiply, you
8594: should either
8595: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8596: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8598: Level: intermediate
8600: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8601: @*/
8602: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8603: {
8605: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8606: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8607: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8612: MatCheckPreallocated(A,1);
8613: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8614: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8617: MatCheckPreallocated(B,2);
8618: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8619: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8621: 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);
8622: if (scall == MAT_REUSE_MATRIX) {
8625: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8626: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8627: (*(*C)->ops->matmultnumeric)(A,B,*C);
8628: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8629: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8630: return(0);
8631: }
8632: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8633: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8635: fA = A->ops->matmult;
8636: fB = B->ops->matmult;
8637: if (fB == fA) {
8638: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8639: mult = fB;
8640: } else {
8641: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8642: char multname[256];
8643: PetscStrcpy(multname,"MatMatMult_");
8644: PetscStrcat(multname,((PetscObject)A)->type_name);
8645: PetscStrcat(multname,"_");
8646: PetscStrcat(multname,((PetscObject)B)->type_name);
8647: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8648: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8649: 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);
8650: }
8651: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8652: (*mult)(A,B,scall,fill,C);
8653: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8654: return(0);
8655: }
8659: /*@
8660: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8661: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8663: Neighbor-wise Collective on Mat
8665: Input Parameters:
8666: + A - the left matrix
8667: . B - the right matrix
8668: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8669: if C is a dense matrix this is irrelevent
8671: Output Parameters:
8672: . C - the product matrix
8674: Notes:
8675: Unless scall is MAT_REUSE_MATRIX C will be created.
8677: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8678: actually needed.
8680: This routine is currently implemented for
8681: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8682: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8683: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8685: Level: intermediate
8687: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8688: We should incorporate them into PETSc.
8690: .seealso: MatMatMult(), MatMatMultNumeric()
8691: @*/
8692: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8693: {
8695: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8696: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8697: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
8702: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8703: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8707: MatCheckPreallocated(B,2);
8708: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8709: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8712: 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);
8713: if (fill == PETSC_DEFAULT) fill = 2.0;
8714: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8715: MatCheckPreallocated(A,1);
8717: Asymbolic = A->ops->matmultsymbolic;
8718: Bsymbolic = B->ops->matmultsymbolic;
8719: if (Asymbolic == Bsymbolic) {
8720: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8721: symbolic = Bsymbolic;
8722: } else { /* dispatch based on the type of A and B */
8723: char symbolicname[256];
8724: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8725: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8726: PetscStrcat(symbolicname,"_");
8727: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8728: PetscStrcat(symbolicname,"_C");
8729: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8730: 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);
8731: }
8732: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8733: (*symbolic)(A,B,fill,C);
8734: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8735: return(0);
8736: }
8740: /*@
8741: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8742: Call this routine after first calling MatMatMultSymbolic().
8744: Neighbor-wise Collective on Mat
8746: Input Parameters:
8747: + A - the left matrix
8748: - B - the right matrix
8750: Output Parameters:
8751: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8753: Notes:
8754: C must have been created with MatMatMultSymbolic().
8756: This routine is currently implemented for
8757: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8758: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8759: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8761: Level: intermediate
8763: .seealso: MatMatMult(), MatMatMultSymbolic()
8764: @*/
8765: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8766: {
8770: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8771: return(0);
8772: }
8776: /*@
8777: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8779: Neighbor-wise Collective on Mat
8781: Input Parameters:
8782: + A - the left matrix
8783: . B - the right matrix
8784: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8785: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8787: Output Parameters:
8788: . C - the product matrix
8790: Notes:
8791: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8793: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8795: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8796: actually needed.
8798: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8800: Level: intermediate
8802: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8803: @*/
8804: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8805: {
8807: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8808: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8813: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8814: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8817: MatCheckPreallocated(B,2);
8818: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8819: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8821: 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);
8822: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8823: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8824: MatCheckPreallocated(A,1);
8826: fA = A->ops->mattransposemult;
8827: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8828: fB = B->ops->mattransposemult;
8829: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8830: 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);
8832: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8833: if (scall == MAT_INITIAL_MATRIX) {
8834: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8835: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8836: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8837: }
8838: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8839: (*A->ops->mattransposemultnumeric)(A,B,*C);
8840: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8841: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8842: return(0);
8843: }
8847: /*@
8848: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8850: Neighbor-wise Collective on Mat
8852: Input Parameters:
8853: + A - the left matrix
8854: . B - the right matrix
8855: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8856: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8858: Output Parameters:
8859: . C - the product matrix
8861: Notes:
8862: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8864: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8866: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8867: actually needed.
8869: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8870: which inherit from SeqAIJ. C will be of same type as the input matrices.
8872: Level: intermediate
8874: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8875: @*/
8876: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8877: {
8879: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8880: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8881: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
8886: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8887: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8890: MatCheckPreallocated(B,2);
8891: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8892: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8894: 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);
8895: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8896: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8897: MatCheckPreallocated(A,1);
8899: fA = A->ops->transposematmult;
8900: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8901: fB = B->ops->transposematmult;
8902: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8903: if (fB==fA) {
8904: transposematmult = fA;
8905: }
8906: 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);
8907: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8908: (*transposematmult)(A,B,scall,fill,C);
8909: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8910: return(0);
8911: }
8915: /*@
8916: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
8918: Neighbor-wise Collective on Mat
8920: Input Parameters:
8921: + A - the left matrix
8922: . B - the middle matrix
8923: . C - the right matrix
8924: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8925: - 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
8926: if the result is a dense matrix this is irrelevent
8928: Output Parameters:
8929: . D - the product matrix
8931: Notes:
8932: Unless scall is MAT_REUSE_MATRIX D will be created.
8934: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
8936: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8937: actually needed.
8939: If you have many matrices with the same non-zero structure to multiply, you
8940: should either
8941: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8942: $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
8944: Level: intermediate
8946: .seealso: MatMatMult, MatPtAP()
8947: @*/
8948: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
8949: {
8951: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8952: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8953: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8954: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8959: MatCheckPreallocated(A,1);
8960: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8961: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8964: MatCheckPreallocated(B,2);
8965: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8966: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8969: MatCheckPreallocated(C,3);
8970: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8971: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8972: 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);
8973: 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);
8974: if (scall == MAT_REUSE_MATRIX) {
8977: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
8978: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
8979: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
8980: return(0);
8981: }
8982: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8983: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8985: fA = A->ops->matmatmult;
8986: fB = B->ops->matmatmult;
8987: fC = C->ops->matmatmult;
8988: if (fA == fB && fA == fC) {
8989: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8990: mult = fA;
8991: } else {
8992: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
8993: char multname[256];
8994: PetscStrcpy(multname,"MatMatMatMult_");
8995: PetscStrcat(multname,((PetscObject)A)->type_name);
8996: PetscStrcat(multname,"_");
8997: PetscStrcat(multname,((PetscObject)B)->type_name);
8998: PetscStrcat(multname,"_");
8999: PetscStrcat(multname,((PetscObject)C)->type_name);
9000: PetscStrcat(multname,"_C");
9001: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9002: 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);
9003: }
9004: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9005: (*mult)(A,B,C,scall,fill,D);
9006: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9007: return(0);
9008: }
9012: /*@C
9013: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9015: Collective on Mat
9017: Input Parameters:
9018: + mat - the matrix
9019: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9020: . subcomm - MPI communicator split from the communicator where mat resides in
9021: . mlocal_red - number of local rows of the redundant matrix
9022: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9024: Output Parameter:
9025: . matredundant - redundant matrix
9027: Notes:
9028: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9029: original matrix has not changed from that last call to MatGetRedundantMatrix().
9031: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9032: calling it.
9034: Only MPIAIJ matrix is supported.
9036: Level: advanced
9038: Concepts: subcommunicator
9039: Concepts: duplicate matrix
9041: .seealso: MatDestroy()
9042: @*/
9043: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
9044: {
9049: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9052: }
9053: if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9054: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9055: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9056: MatCheckPreallocated(mat,1);
9058: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9059: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
9060: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9061: return(0);
9062: }
9066: /*@C
9067: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9068: a given 'mat' object. Each submatrix can span multiple procs.
9070: Collective on Mat
9072: Input Parameters:
9073: + mat - the matrix
9074: . subcomm - the subcommunicator obtained by com_split(comm)
9075: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9077: Output Parameter:
9078: . subMat - 'parallel submatrices each spans a given subcomm
9080: Notes:
9081: The submatrix partition across processors is dictated by 'subComm' a
9082: communicator obtained by com_split(comm). The comm_split
9083: is not restriced to be grouped with consecutive original ranks.
9085: Due the comm_split() usage, the parallel layout of the submatrices
9086: map directly to the layout of the original matrix [wrt the local
9087: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9088: into the 'DiagonalMat' of the subMat, hence it is used directly from
9089: the subMat. However the offDiagMat looses some columns - and this is
9090: reconstructed with MatSetValues()
9092: Level: advanced
9094: Concepts: subcommunicator
9095: Concepts: submatrices
9097: .seealso: MatGetSubMatrices()
9098: @*/
9099: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9100: {
9102: PetscMPIInt commsize,subCommSize;
9105: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9106: MPI_Comm_size(subComm,&subCommSize);
9107: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9109: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9110: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9111: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9112: return(0);
9113: }
9117: /*@
9118: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9120: Not Collective
9122: Input Arguments:
9123: mat - matrix to extract local submatrix from
9124: isrow - local row indices for submatrix
9125: iscol - local column indices for submatrix
9127: Output Arguments:
9128: submat - the submatrix
9130: Level: intermediate
9132: Notes:
9133: The submat should be returned with MatRestoreLocalSubMatrix().
9135: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9136: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9138: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9139: MatSetValuesBlockedLocal() will also be implemented.
9141: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9142: @*/
9143: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9144: {
9154: if (mat->ops->getlocalsubmatrix) {
9155: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9156: } else {
9157: MatCreateLocalRef(mat,isrow,iscol,submat);
9158: }
9159: return(0);
9160: }
9164: /*@
9165: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9167: Not Collective
9169: Input Arguments:
9170: mat - matrix to extract local submatrix from
9171: isrow - local row indices for submatrix
9172: iscol - local column indices for submatrix
9173: submat - the submatrix
9175: Level: intermediate
9177: .seealso: MatGetLocalSubMatrix()
9178: @*/
9179: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9180: {
9189: if (*submat) {
9191: }
9193: if (mat->ops->restorelocalsubmatrix) {
9194: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9195: } else {
9196: MatDestroy(submat);
9197: }
9198: *submat = NULL;
9199: return(0);
9200: }
9202: /* --------------------------------------------------------*/
9205: /*@
9206: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9208: Collective on Mat
9210: Input Parameter:
9211: . mat - the matrix
9213: Output Parameter:
9214: . is - if any rows have zero diagonals this contains the list of them
9216: Level: developer
9218: Concepts: matrix-vector product
9220: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9221: @*/
9222: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9223: {
9229: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9230: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9232: if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9233: (*mat->ops->findzerodiagonals)(mat,is);
9234: return(0);
9235: }
9239: /*@C
9240: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9242: Collective on Mat
9244: Input Parameters:
9245: . mat - the matrix
9247: Output Parameters:
9248: . values - the block inverses in column major order (FORTRAN-like)
9250: Note:
9251: This routine is not available from Fortran.
9253: Level: advanced
9254: @*/
9255: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9256: {
9261: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9262: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9263: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9264: (*mat->ops->invertblockdiagonal)(mat,values);
9265: return(0);
9266: }
9270: /*@C
9271: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9272: via MatTransposeColoringCreate().
9274: Collective on MatTransposeColoring
9276: Input Parameter:
9277: . c - coloring context
9279: Level: intermediate
9281: .seealso: MatTransposeColoringCreate()
9282: @*/
9283: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9284: {
9285: PetscErrorCode ierr;
9286: MatTransposeColoring matcolor=*c;
9289: if (!matcolor) return(0);
9290: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9292: PetscFree(matcolor->ncolumns);
9293: PetscFree(matcolor->nrows);
9294: PetscFree(matcolor->colorforrow);
9295: PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9296: PetscFree(matcolor->colorforcol);
9297: PetscFree(matcolor->columns);
9298: PetscHeaderDestroy(c);
9299: return(0);
9300: }
9304: /*@C
9305: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9306: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9307: MatTransposeColoring to sparse B.
9309: Collective on MatTransposeColoring
9311: Input Parameters:
9312: + B - sparse matrix B
9313: . Btdense - symbolic dense matrix B^T
9314: - coloring - coloring context created with MatTransposeColoringCreate()
9316: Output Parameter:
9317: . Btdense - dense matrix B^T
9319: Options Database Keys:
9320: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9321: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9322: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9324: Level: intermediate
9326: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9328: .keywords: coloring
9329: @*/
9330: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9331: {
9339: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9340: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9341: return(0);
9342: }
9346: /*@C
9347: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9348: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9349: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9350: Csp from Cden.
9352: Collective on MatTransposeColoring
9354: Input Parameters:
9355: + coloring - coloring context created with MatTransposeColoringCreate()
9356: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9358: Output Parameter:
9359: . Csp - sparse matrix
9361: Options Database Keys:
9362: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9363: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9364: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9366: Level: intermediate
9368: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9370: .keywords: coloring
9371: @*/
9372: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9373: {
9381: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9382: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9383: return(0);
9384: }
9388: /*@C
9389: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9391: Collective on Mat
9393: Input Parameters:
9394: + mat - the matrix product C
9395: - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9397: Output Parameter:
9398: . color - the new coloring context
9400: Level: intermediate
9402: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9403: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9404: @*/
9405: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9406: {
9407: MatTransposeColoring c;
9408: MPI_Comm comm;
9409: PetscErrorCode ierr;
9412: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9413: PetscObjectGetComm((PetscObject)mat,&comm);
9414: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9416: c->ctype = iscoloring->ctype;
9417: if (mat->ops->transposecoloringcreate) {
9418: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9419: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
9421: *color = c;
9422: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9423: return(0);
9424: }