Actual source code: matrix.c
petsc-3.4.4 2014-03-13
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: {
5713: PetscMPIInt size;
5719: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5720: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5721: MatCheckPreallocated(mat,1);
5723: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5724: if (mat->ops->zerorowslocal) {
5725: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
5726: } else if (size == 1) {
5727: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5728: } else {
5729: IS is, newis;
5730: const PetscInt *newRows;
5732: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5733: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5734: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
5735: ISGetIndices(newis,&newRows);
5736: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
5737: ISRestoreIndices(newis,&newRows);
5738: ISDestroy(&newis);
5739: ISDestroy(&is);
5740: }
5741: PetscObjectStateIncrease((PetscObject)mat);
5742: #if defined(PETSC_HAVE_CUSP)
5743: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5744: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5745: }
5746: #endif
5747: return(0);
5748: }
5752: /*@C
5753: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
5754: of a set of rows of a matrix; using local numbering of rows.
5756: Collective on Mat
5758: Input Parameters:
5759: + mat - the matrix
5760: . is - index set of rows to remove
5761: . diag - value put in all diagonals of eliminated rows
5762: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5763: - b - optional vector of right hand side, that will be adjusted by provided solution
5765: Notes:
5766: Before calling MatZeroRowsLocalIS(), the user must first set the
5767: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5769: For the AIJ matrix formats this removes the old nonzero structure,
5770: but does not release memory. For the dense and block diagonal
5771: formats this does not alter the nonzero structure.
5773: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5774: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5775: merely zeroed.
5777: The user can set a value in the diagonal entry (or for the AIJ and
5778: row formats can optionally remove the main diagonal entry from the
5779: nonzero structure as well, by passing 0.0 as the final argument).
5781: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5782: owns that are to be zeroed. This saves a global synchronization in the implementation.
5784: Level: intermediate
5786: Concepts: matrices^zeroing
5788: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5789: @*/
5790: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5791: {
5793: PetscInt numRows;
5794: const PetscInt *rows;
5800: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5801: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5802: MatCheckPreallocated(mat,1);
5804: ISGetLocalSize(is,&numRows);
5805: ISGetIndices(is,&rows);
5806: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
5807: ISRestoreIndices(is,&rows);
5808: return(0);
5809: }
5813: /*@C
5814: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
5815: of a set of rows and columns of a matrix; using local numbering of rows.
5817: Collective on Mat
5819: Input Parameters:
5820: + mat - the matrix
5821: . numRows - the number of rows to remove
5822: . rows - the global row indices
5823: . diag - value put in all diagonals of eliminated rows
5824: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5825: - b - optional vector of right hand side, that will be adjusted by provided solution
5827: Notes:
5828: Before calling MatZeroRowsColumnsLocal(), the user must first set the
5829: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5831: The user can set a value in the diagonal entry (or for the AIJ and
5832: row formats can optionally remove the main diagonal entry from the
5833: nonzero structure as well, by passing 0.0 as the final argument).
5835: Level: intermediate
5837: Concepts: matrices^zeroing
5839: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5840: @*/
5841: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5842: {
5844: PetscMPIInt size;
5850: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5851: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5852: MatCheckPreallocated(mat,1);
5854: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
5855: if (size == 1) {
5856: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5857: } else {
5858: IS is, newis;
5859: const PetscInt *newRows;
5861: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
5862: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
5863: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
5864: ISGetIndices(newis,&newRows);
5865: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
5866: ISRestoreIndices(newis,&newRows);
5867: ISDestroy(&newis);
5868: ISDestroy(&is);
5869: }
5870: PetscObjectStateIncrease((PetscObject)mat);
5871: #if defined(PETSC_HAVE_CUSP)
5872: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5873: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5874: }
5875: #endif
5876: return(0);
5877: }
5881: /*@C
5882: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
5883: of a set of rows and columns of a matrix; using local numbering of rows.
5885: Collective on Mat
5887: Input Parameters:
5888: + mat - the matrix
5889: . is - index set of rows to remove
5890: . diag - value put in all diagonals of eliminated rows
5891: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5892: - b - optional vector of right hand side, that will be adjusted by provided solution
5894: Notes:
5895: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
5896: local-to-global mapping by calling MatSetLocalToGlobalMapping().
5898: The user can set a value in the diagonal entry (or for the AIJ and
5899: row formats can optionally remove the main diagonal entry from the
5900: nonzero structure as well, by passing 0.0 as the final argument).
5902: Level: intermediate
5904: Concepts: matrices^zeroing
5906: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
5907: @*/
5908: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5909: {
5911: PetscInt numRows;
5912: const PetscInt *rows;
5918: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5919: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5920: MatCheckPreallocated(mat,1);
5922: ISGetLocalSize(is,&numRows);
5923: ISGetIndices(is,&rows);
5924: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
5925: ISRestoreIndices(is,&rows);
5926: return(0);
5927: }
5931: /*@
5932: MatGetSize - Returns the numbers of rows and columns in a matrix.
5934: Not Collective
5936: Input Parameter:
5937: . mat - the matrix
5939: Output Parameters:
5940: + m - the number of global rows
5941: - n - the number of global columns
5943: Note: both output parameters can be NULL on input.
5945: Level: beginner
5947: Concepts: matrices^size
5949: .seealso: MatGetLocalSize()
5950: @*/
5951: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
5952: {
5955: if (m) *m = mat->rmap->N;
5956: if (n) *n = mat->cmap->N;
5957: return(0);
5958: }
5962: /*@
5963: MatGetLocalSize - Returns the number of rows and columns in a matrix
5964: stored locally. This information may be implementation dependent, so
5965: use with care.
5967: Not Collective
5969: Input Parameters:
5970: . mat - the matrix
5972: Output Parameters:
5973: + m - the number of local rows
5974: - n - the number of local columns
5976: Note: both output parameters can be NULL on input.
5978: Level: beginner
5980: Concepts: matrices^local size
5982: .seealso: MatGetSize()
5983: @*/
5984: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
5985: {
5990: if (m) *m = mat->rmap->n;
5991: if (n) *n = mat->cmap->n;
5992: return(0);
5993: }
5997: /*@
5998: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
5999: this processor. (The columns of the "diagonal block")
6001: Not Collective, unless matrix has not been allocated, then collective on Mat
6003: Input Parameters:
6004: . mat - the matrix
6006: Output Parameters:
6007: + m - the global index of the first local column
6008: - n - one more than the global index of the last local column
6010: Notes: both output parameters can be NULL on input.
6012: Level: developer
6014: Concepts: matrices^column ownership
6016: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6018: @*/
6019: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6020: {
6026: MatCheckPreallocated(mat,1);
6027: if (m) *m = mat->cmap->rstart;
6028: if (n) *n = mat->cmap->rend;
6029: return(0);
6030: }
6034: /*@
6035: MatGetOwnershipRange - Returns the range of matrix rows owned by
6036: this processor, assuming that the matrix is laid out with the first
6037: n1 rows on the first processor, the next n2 rows on the second, etc.
6038: For certain parallel layouts this range may not be well defined.
6040: Not Collective
6042: Input Parameters:
6043: . mat - the matrix
6045: Output Parameters:
6046: + m - the global index of the first local row
6047: - n - one more than the global index of the last local row
6049: Note: Both output parameters can be NULL on input.
6050: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6051: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6052: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6054: Level: beginner
6056: Concepts: matrices^row ownership
6058: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6060: @*/
6061: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6062: {
6068: MatCheckPreallocated(mat,1);
6069: if (m) *m = mat->rmap->rstart;
6070: if (n) *n = mat->rmap->rend;
6071: return(0);
6072: }
6076: /*@C
6077: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6078: each process
6080: Not Collective, unless matrix has not been allocated, then collective on Mat
6082: Input Parameters:
6083: . mat - the matrix
6085: Output Parameters:
6086: . ranges - start of each processors portion plus one more then the total length at the end
6088: Level: beginner
6090: Concepts: matrices^row ownership
6092: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6094: @*/
6095: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6096: {
6102: MatCheckPreallocated(mat,1);
6103: PetscLayoutGetRanges(mat->rmap,ranges);
6104: return(0);
6105: }
6109: /*@C
6110: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6111: this processor. (The columns of the "diagonal blocks" for each process)
6113: Not Collective, unless matrix has not been allocated, then collective on Mat
6115: Input Parameters:
6116: . mat - the matrix
6118: Output Parameters:
6119: . ranges - start of each processors portion plus one more then the total length at the end
6121: Level: beginner
6123: Concepts: matrices^column ownership
6125: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6127: @*/
6128: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6129: {
6135: MatCheckPreallocated(mat,1);
6136: PetscLayoutGetRanges(mat->cmap,ranges);
6137: return(0);
6138: }
6142: /*@C
6143: MatGetOwnershipIS - Get row and column ownership as index sets
6145: Not Collective
6147: Input Arguments:
6148: . A - matrix of type Elemental
6150: Output Arguments:
6151: + rows - rows in which this process owns elements
6152: . cols - columns in which this process owns elements
6154: Level: intermediate
6156: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6157: @*/
6158: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6159: {
6160: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6163: MatCheckPreallocated(A,1);
6164: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6165: if (f) {
6166: (*f)(A,rows,cols);
6167: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6168: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6169: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6170: }
6171: return(0);
6172: }
6176: /*@C
6177: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6178: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6179: to complete the factorization.
6181: Collective on Mat
6183: Input Parameters:
6184: + mat - the matrix
6185: . row - row permutation
6186: . column - column permutation
6187: - info - structure containing
6188: $ levels - number of levels of fill.
6189: $ expected fill - as ratio of original fill.
6190: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6191: missing diagonal entries)
6193: Output Parameters:
6194: . fact - new matrix that has been symbolically factored
6196: Notes:
6197: See the <a href="../../docs/manual.pdf">users manual</a> for additional information about
6198: choosing the fill factor for better efficiency.
6200: Most users should employ the simplified KSP interface for linear solvers
6201: instead of working directly with matrix algebra routines such as this.
6202: See, e.g., KSPCreate().
6204: Level: developer
6206: Concepts: matrices^symbolic LU factorization
6207: Concepts: matrices^factorization
6208: Concepts: LU^symbolic factorization
6210: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6211: MatGetOrdering(), MatFactorInfo
6213: Developer Note: fortran interface is not autogenerated as the f90
6214: interface defintion cannot be generated correctly [due to MatFactorInfo]
6216: @*/
6217: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6218: {
6228: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6229: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6230: if (!(fact)->ops->ilufactorsymbolic) {
6231: const MatSolverPackage spackage;
6232: MatFactorGetSolverPackage(fact,&spackage);
6233: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6234: }
6235: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6236: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6237: MatCheckPreallocated(mat,2);
6239: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6240: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6241: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6242: return(0);
6243: }
6247: /*@C
6248: MatICCFactorSymbolic - Performs symbolic incomplete
6249: Cholesky factorization for a symmetric matrix. Use
6250: MatCholeskyFactorNumeric() to complete the factorization.
6252: Collective on Mat
6254: Input Parameters:
6255: + mat - the matrix
6256: . perm - row and column permutation
6257: - info - structure containing
6258: $ levels - number of levels of fill.
6259: $ expected fill - as ratio of original fill.
6261: Output Parameter:
6262: . fact - the factored matrix
6264: Notes:
6265: Most users should employ the KSP interface for linear solvers
6266: instead of working directly with matrix algebra routines such as this.
6267: See, e.g., KSPCreate().
6269: Level: developer
6271: Concepts: matrices^symbolic incomplete Cholesky factorization
6272: Concepts: matrices^factorization
6273: Concepts: Cholsky^symbolic factorization
6275: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6277: Developer Note: fortran interface is not autogenerated as the f90
6278: interface defintion cannot be generated correctly [due to MatFactorInfo]
6280: @*/
6281: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6282: {
6291: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6292: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6293: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %G",info->fill);
6294: if (!(fact)->ops->iccfactorsymbolic) {
6295: const MatSolverPackage spackage;
6296: MatFactorGetSolverPackage(fact,&spackage);
6297: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6298: }
6299: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6300: MatCheckPreallocated(mat,2);
6302: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6303: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6304: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6305: return(0);
6306: }
6310: /*@C
6311: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6312: points to an array of valid matrices, they may be reused to store the new
6313: submatrices.
6315: Collective on Mat
6317: Input Parameters:
6318: + mat - the matrix
6319: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6320: . irow, icol - index sets of rows and columns to extract (must be sorted)
6321: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6323: Output Parameter:
6324: . submat - the array of submatrices
6326: Notes:
6327: MatGetSubMatrices() can extract ONLY sequential submatrices
6328: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6329: to extract a parallel submatrix.
6331: Currently both row and column indices must be sorted to guarantee
6332: correctness with all matrix types.
6334: When extracting submatrices from a parallel matrix, each processor can
6335: form a different submatrix by setting the rows and columns of its
6336: individual index sets according to the local submatrix desired.
6338: When finished using the submatrices, the user should destroy
6339: them with MatDestroyMatrices().
6341: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6342: original matrix has not changed from that last call to MatGetSubMatrices().
6344: This routine creates the matrices in submat; you should NOT create them before
6345: calling it. It also allocates the array of matrix pointers submat.
6347: For BAIJ matrices the index sets must respect the block structure, that is if they
6348: request one row/column in a block, they must request all rows/columns that are in
6349: that block. For example, if the block size is 2 you cannot request just row 0 and
6350: column 0.
6352: Fortran Note:
6353: The Fortran interface is slightly different from that given below; it
6354: requires one to pass in as submat a Mat (integer) array of size at least m.
6356: Level: advanced
6358: Concepts: matrices^accessing submatrices
6359: Concepts: submatrices
6361: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6362: @*/
6363: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6364: {
6366: PetscInt i;
6367: PetscBool eq;
6372: if (n) {
6377: }
6379: if (n && scall == MAT_REUSE_MATRIX) {
6382: }
6383: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6384: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6385: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6386: MatCheckPreallocated(mat,1);
6388: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6389: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6390: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6391: for (i=0; i<n; i++) {
6392: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6393: ISEqual(irow[i],icol[i],&eq);
6394: if (eq) {
6395: if (mat->symmetric) {
6396: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6397: } else if (mat->hermitian) {
6398: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6399: } else if (mat->structurally_symmetric) {
6400: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6401: }
6402: }
6403: }
6404: }
6405: return(0);
6406: }
6410: PetscErrorCode MatGetSubMatricesParallel(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6411: {
6413: PetscInt i;
6414: PetscBool eq;
6419: if (n) {
6424: }
6426: if (n && scall == MAT_REUSE_MATRIX) {
6429: }
6430: if (!mat->ops->getsubmatricesparallel) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6431: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6432: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6433: MatCheckPreallocated(mat,1);
6435: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6436: (*mat->ops->getsubmatricesparallel)(mat,n,irow,icol,scall,submat);
6437: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6438: for (i=0; i<n; i++) {
6439: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6440: ISEqual(irow[i],icol[i],&eq);
6441: if (eq) {
6442: if (mat->symmetric) {
6443: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6444: } else if (mat->hermitian) {
6445: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6446: } else if (mat->structurally_symmetric) {
6447: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6448: }
6449: }
6450: }
6451: }
6452: return(0);
6453: }
6457: /*@C
6458: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6460: Collective on Mat
6462: Input Parameters:
6463: + n - the number of local matrices
6464: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6465: sequence of MatGetSubMatrices())
6467: Level: advanced
6469: Notes: Frees not only the matrices, but also the array that contains the matrices
6470: In Fortran will not free the array.
6472: .seealso: MatGetSubMatrices()
6473: @*/
6474: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6475: {
6477: PetscInt i;
6480: if (!*mat) return(0);
6481: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6483: for (i=0; i<n; i++) {
6484: MatDestroy(&(*mat)[i]);
6485: }
6486: /* memory is allocated even if n = 0 */
6487: PetscFree(*mat);
6488: *mat = NULL;
6489: return(0);
6490: }
6494: /*@C
6495: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6497: Collective on Mat
6499: Input Parameters:
6500: . mat - the matrix
6502: Output Parameter:
6503: . matstruct - the sequential matrix with the nonzero structure of mat
6505: Level: intermediate
6507: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6508: @*/
6509: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6510: {
6518: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6519: MatCheckPreallocated(mat,1);
6521: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6522: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6523: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6524: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6525: return(0);
6526: }
6530: /*@C
6531: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6533: Collective on Mat
6535: Input Parameters:
6536: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6537: sequence of MatGetSequentialNonzeroStructure())
6539: Level: advanced
6541: Notes: Frees not only the matrices, but also the array that contains the matrices
6543: .seealso: MatGetSeqNonzeroStructure()
6544: @*/
6545: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6546: {
6551: MatDestroy(mat);
6552: return(0);
6553: }
6557: /*@
6558: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6559: replaces the index sets by larger ones that represent submatrices with
6560: additional overlap.
6562: Collective on Mat
6564: Input Parameters:
6565: + mat - the matrix
6566: . n - the number of index sets
6567: . is - the array of index sets (these index sets will changed during the call)
6568: - ov - the additional overlap requested
6570: Level: developer
6572: Concepts: overlap
6573: Concepts: ASM^computing overlap
6575: .seealso: MatGetSubMatrices()
6576: @*/
6577: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6578: {
6584: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6585: if (n) {
6588: }
6589: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6590: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6591: MatCheckPreallocated(mat,1);
6593: if (!ov) return(0);
6594: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6595: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6596: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6597: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6598: return(0);
6599: }
6603: /*@
6604: MatGetBlockSize - Returns the matrix block size; useful especially for the
6605: block row and block diagonal formats.
6607: Not Collective
6609: Input Parameter:
6610: . mat - the matrix
6612: Output Parameter:
6613: . bs - block size
6615: Notes:
6616: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6618: Level: intermediate
6620: Concepts: matrices^block size
6622: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
6623: @*/
6624: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
6625: {
6630: MatCheckPreallocated(mat,1);
6631: *bs = mat->rmap->bs;
6632: return(0);
6633: }
6637: /*@
6638: MatGetBlockSizes - Returns the matrix block row and column sizes;
6639: useful especially for the block row and block diagonal formats.
6641: Not Collective
6643: Input Parameter:
6644: . mat - the matrix
6646: Output Parameter:
6647: . rbs - row block size
6648: . cbs - coumn block size
6650: Notes:
6651: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ
6653: Level: intermediate
6655: Concepts: matrices^block size
6657: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6658: @*/
6659: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
6660: {
6666: MatCheckPreallocated(mat,1);
6667: if (rbs) *rbs = mat->rmap->bs;
6668: if (cbs) *cbs = mat->cmap->bs;
6669: return(0);
6670: }
6674: /*@
6675: MatSetBlockSize - Sets the matrix block size.
6677: Logically Collective on Mat
6679: Input Parameters:
6680: + mat - the matrix
6681: - bs - block size
6683: Notes:
6684: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6686: Level: intermediate
6688: Concepts: matrices^block size
6690: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6691: @*/
6692: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
6693: {
6699: PetscLayoutSetBlockSize(mat->rmap,bs);
6700: PetscLayoutSetBlockSize(mat->cmap,bs);
6701: return(0);
6702: }
6706: /*@
6707: MatSetBlockSizes - Sets the matrix block row and column sizes.
6709: Logically Collective on Mat
6711: Input Parameters:
6712: + mat - the matrix
6713: - rbs - row block size
6714: - cbs - column block size
6716: Notes:
6717: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
6719: Level: intermediate
6721: Concepts: matrices^block size
6723: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize()
6724: @*/
6725: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
6726: {
6733: PetscLayoutSetBlockSize(mat->rmap,rbs);
6734: PetscLayoutSetBlockSize(mat->cmap,cbs);
6735: return(0);
6736: }
6740: /*@C
6741: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
6743: Collective on Mat
6745: Input Parameters:
6746: + mat - the matrix
6747: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
6748: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
6749: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6750: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6751: always used.
6753: Output Parameters:
6754: + n - number of rows in the (possibly compressed) matrix
6755: . ia - the row pointers [of length n+1]
6756: . ja - the column indices
6757: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
6758: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
6760: Level: developer
6762: Notes: You CANNOT change any of the ia[] or ja[] values.
6764: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
6766: Fortran Node
6768: In Fortran use
6769: $ PetscInt ia(1), ja(1)
6770: $ PetscOffset iia, jja
6771: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
6772: $
6773: $ or
6774: $
6775: $ PetscScalar, pointer :: xx_v(:)
6776: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
6779: Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
6781: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
6782: @*/
6783: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6784: {
6794: MatCheckPreallocated(mat,1);
6795: if (!mat->ops->getrowij) *done = PETSC_FALSE;
6796: else {
6797: *done = PETSC_TRUE;
6798: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
6799: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6800: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
6801: }
6802: return(0);
6803: }
6807: /*@C
6808: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
6810: Collective on Mat
6812: Input Parameters:
6813: + mat - the matrix
6814: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6815: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6816: symmetrized
6817: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6818: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6819: always used.
6821: Output Parameters:
6822: + n - number of columns in the (possibly compressed) matrix
6823: . ia - the column pointers
6824: . ja - the row indices
6825: - done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
6827: Level: developer
6829: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6830: @*/
6831: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6832: {
6842: MatCheckPreallocated(mat,1);
6843: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
6844: else {
6845: *done = PETSC_TRUE;
6846: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6847: }
6848: return(0);
6849: }
6853: /*@C
6854: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
6855: MatGetRowIJ().
6857: Collective on Mat
6859: Input Parameters:
6860: + mat - the matrix
6861: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6862: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6863: symmetrized
6864: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6865: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6866: always used.
6868: Output Parameters:
6869: + n - size of (possibly compressed) matrix
6870: . ia - the row pointers
6871: . ja - the column indices
6872: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6874: Level: developer
6876: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
6877: @*/
6878: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6879: {
6888: MatCheckPreallocated(mat,1);
6890: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
6891: else {
6892: *done = PETSC_TRUE;
6893: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6894: if (n) *n = 0;
6895: if (ia) *ia = NULL;
6896: if (ja) *ja = NULL;
6897: }
6898: return(0);
6899: }
6903: /*@C
6904: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
6905: MatGetColumnIJ().
6907: Collective on Mat
6909: Input Parameters:
6910: + mat - the matrix
6911: . shift - 1 or zero indicating we want the indices starting at 0 or 1
6912: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
6913: symmetrized
6914: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
6915: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
6916: always used.
6918: Output Parameters:
6919: + n - size of (possibly compressed) matrix
6920: . ia - the column pointers
6921: . ja - the row indices
6922: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
6924: Level: developer
6926: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
6927: @*/
6928: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
6929: {
6938: MatCheckPreallocated(mat,1);
6940: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
6941: else {
6942: *done = PETSC_TRUE;
6943: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
6944: if (n) *n = 0;
6945: if (ia) *ia = NULL;
6946: if (ja) *ja = NULL;
6947: }
6948: return(0);
6949: }
6953: /*@C
6954: MatColoringPatch -Used inside matrix coloring routines that
6955: use MatGetRowIJ() and/or MatGetColumnIJ().
6957: Collective on Mat
6959: Input Parameters:
6960: + mat - the matrix
6961: . ncolors - max color value
6962: . n - number of entries in colorarray
6963: - colorarray - array indicating color for each column
6965: Output Parameters:
6966: . iscoloring - coloring generated using colorarray information
6968: Level: developer
6970: .seealso: MatGetRowIJ(), MatGetColumnIJ()
6972: @*/
6973: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
6974: {
6982: MatCheckPreallocated(mat,1);
6984: if (!mat->ops->coloringpatch) {
6985: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,iscoloring);
6986: } else {
6987: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
6988: }
6989: return(0);
6990: }
6995: /*@
6996: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
6998: Logically Collective on Mat
7000: Input Parameter:
7001: . mat - the factored matrix to be reset
7003: Notes:
7004: This routine should be used only with factored matrices formed by in-place
7005: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7006: format). This option can save memory, for example, when solving nonlinear
7007: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7008: ILU(0) preconditioner.
7010: Note that one can specify in-place ILU(0) factorization by calling
7011: .vb
7012: PCType(pc,PCILU);
7013: PCFactorSeUseInPlace(pc);
7014: .ve
7015: or by using the options -pc_type ilu -pc_factor_in_place
7017: In-place factorization ILU(0) can also be used as a local
7018: solver for the blocks within the block Jacobi or additive Schwarz
7019: methods (runtime option: -sub_pc_factor_in_place). See the discussion
7020: of these preconditioners in the <a href="../../docs/manual.pdf#ch_pc">PC chapter of the users manual</a> for details on setting
7021: local solver options.
7023: Most users should employ the simplified KSP interface for linear solvers
7024: instead of working directly with matrix algebra routines such as this.
7025: See, e.g., KSPCreate().
7027: Level: developer
7029: .seealso: PCFactorSetUseInPlace()
7031: Concepts: matrices^unfactored
7033: @*/
7034: PetscErrorCode MatSetUnfactored(Mat mat)
7035: {
7041: MatCheckPreallocated(mat,1);
7042: mat->factortype = MAT_FACTOR_NONE;
7043: if (!mat->ops->setunfactored) return(0);
7044: (*mat->ops->setunfactored)(mat);
7045: return(0);
7046: }
7048: /*MC
7049: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7051: Synopsis:
7052: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7054: Not collective
7056: Input Parameter:
7057: . x - matrix
7059: Output Parameters:
7060: + xx_v - the Fortran90 pointer to the array
7061: - ierr - error code
7063: Example of Usage:
7064: .vb
7065: PetscScalar, pointer xx_v(:,:)
7066: ....
7067: call MatDenseGetArrayF90(x,xx_v,ierr)
7068: a = xx_v(3)
7069: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7070: .ve
7072: Level: advanced
7074: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7076: Concepts: matrices^accessing array
7078: M*/
7080: /*MC
7081: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7082: accessed with MatDenseGetArrayF90().
7084: Synopsis:
7085: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7087: Not collective
7089: Input Parameters:
7090: + x - matrix
7091: - xx_v - the Fortran90 pointer to the array
7093: Output Parameter:
7094: . ierr - error code
7096: Example of Usage:
7097: .vb
7098: PetscScalar, pointer xx_v(:)
7099: ....
7100: call MatDenseGetArrayF90(x,xx_v,ierr)
7101: a = xx_v(3)
7102: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7103: .ve
7105: Level: advanced
7107: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7109: M*/
7112: /*MC
7113: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7115: Synopsis:
7116: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7118: Not collective
7120: Input Parameter:
7121: . x - matrix
7123: Output Parameters:
7124: + xx_v - the Fortran90 pointer to the array
7125: - ierr - error code
7127: Example of Usage:
7128: .vb
7129: PetscScalar, pointer xx_v(:,:)
7130: ....
7131: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7132: a = xx_v(3)
7133: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7134: .ve
7136: Level: advanced
7138: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7140: Concepts: matrices^accessing array
7142: M*/
7144: /*MC
7145: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7146: accessed with MatSeqAIJGetArrayF90().
7148: Synopsis:
7149: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7151: Not collective
7153: Input Parameters:
7154: + x - matrix
7155: - xx_v - the Fortran90 pointer to the array
7157: Output Parameter:
7158: . ierr - error code
7160: Example of Usage:
7161: .vb
7162: PetscScalar, pointer xx_v(:)
7163: ....
7164: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7165: a = xx_v(3)
7166: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7167: .ve
7169: Level: advanced
7171: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7173: M*/
7178: /*@
7179: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7180: as the original matrix.
7182: Collective on Mat
7184: Input Parameters:
7185: + mat - the original matrix
7186: . isrow - parallel IS containing the rows this processor should obtain
7187: . 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.
7188: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7190: Output Parameter:
7191: . newmat - the new submatrix, of the same type as the old
7193: Level: advanced
7195: Notes:
7196: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7198: The rows in isrow will be sorted into the same order as the original matrix on each process.
7200: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7201: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7202: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7203: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7204: you are finished using it.
7206: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7207: the input matrix.
7209: If iscol is NULL then all columns are obtained (not supported in Fortran).
7211: Example usage:
7212: Consider the following 8x8 matrix with 34 non-zero values, that is
7213: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7214: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7215: as follows:
7217: .vb
7218: 1 2 0 | 0 3 0 | 0 4
7219: Proc0 0 5 6 | 7 0 0 | 8 0
7220: 9 0 10 | 11 0 0 | 12 0
7221: -------------------------------------
7222: 13 0 14 | 15 16 17 | 0 0
7223: Proc1 0 18 0 | 19 20 21 | 0 0
7224: 0 0 0 | 22 23 0 | 24 0
7225: -------------------------------------
7226: Proc2 25 26 27 | 0 0 28 | 29 0
7227: 30 0 0 | 31 32 33 | 0 34
7228: .ve
7230: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7232: .vb
7233: 2 0 | 0 3 0 | 0
7234: Proc0 5 6 | 7 0 0 | 8
7235: -------------------------------
7236: Proc1 18 0 | 19 20 21 | 0
7237: -------------------------------
7238: Proc2 26 27 | 0 0 28 | 29
7239: 0 0 | 31 32 33 | 0
7240: .ve
7243: Concepts: matrices^submatrices
7245: .seealso: MatGetSubMatrices()
7246: @*/
7247: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7248: {
7250: PetscMPIInt size;
7251: Mat *local;
7252: IS iscoltmp;
7261: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7262: MatCheckPreallocated(mat,1);
7263: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7265: if (!iscol) {
7266: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7267: } else {
7268: iscoltmp = iscol;
7269: }
7271: /* if original matrix is on just one processor then use submatrix generated */
7272: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7273: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7274: if (!iscol) {ISDestroy(&iscoltmp);}
7275: return(0);
7276: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7277: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7278: *newmat = *local;
7279: PetscFree(local);
7280: if (!iscol) {ISDestroy(&iscoltmp);}
7281: return(0);
7282: } else if (!mat->ops->getsubmatrix) {
7283: /* Create a new matrix type that implements the operation using the full matrix */
7284: switch (cll) {
7285: case MAT_INITIAL_MATRIX:
7286: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7287: break;
7288: case MAT_REUSE_MATRIX:
7289: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7290: break;
7291: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7292: }
7293: if (!iscol) {ISDestroy(&iscoltmp);}
7294: return(0);
7295: }
7297: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7298: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7299: if (!iscol) {ISDestroy(&iscoltmp);}
7300: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7301: return(0);
7302: }
7306: /*@
7307: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7308: used during the assembly process to store values that belong to
7309: other processors.
7311: Not Collective
7313: Input Parameters:
7314: + mat - the matrix
7315: . size - the initial size of the stash.
7316: - bsize - the initial size of the block-stash(if used).
7318: Options Database Keys:
7319: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7320: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7322: Level: intermediate
7324: Notes:
7325: The block-stash is used for values set with MatSetValuesBlocked() while
7326: the stash is used for values set with MatSetValues()
7328: Run with the option -info and look for output of the form
7329: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7330: to determine the appropriate value, MM, to use for size and
7331: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7332: to determine the value, BMM to use for bsize
7334: Concepts: stash^setting matrix size
7335: Concepts: matrices^stash
7337: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7339: @*/
7340: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7341: {
7347: MatStashSetInitialSize_Private(&mat->stash,size);
7348: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7349: return(0);
7350: }
7354: /*@
7355: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7356: the matrix
7358: Neighbor-wise Collective on Mat
7360: Input Parameters:
7361: + mat - the matrix
7362: . x,y - the vectors
7363: - w - where the result is stored
7365: Level: intermediate
7367: Notes:
7368: w may be the same vector as y.
7370: This allows one to use either the restriction or interpolation (its transpose)
7371: matrix to do the interpolation
7373: Concepts: interpolation
7375: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7377: @*/
7378: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7379: {
7381: PetscInt M,N,Ny;
7389: MatCheckPreallocated(A,1);
7390: MatGetSize(A,&M,&N);
7391: VecGetSize(y,&Ny);
7392: if (M == Ny) {
7393: MatMultAdd(A,x,y,w);
7394: } else {
7395: MatMultTransposeAdd(A,x,y,w);
7396: }
7397: return(0);
7398: }
7402: /*@
7403: MatInterpolate - y = A*x or A'*x depending on the shape of
7404: the matrix
7406: Neighbor-wise Collective on Mat
7408: Input Parameters:
7409: + mat - the matrix
7410: - x,y - the vectors
7412: Level: intermediate
7414: Notes:
7415: This allows one to use either the restriction or interpolation (its transpose)
7416: matrix to do the interpolation
7418: Concepts: matrices^interpolation
7420: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7422: @*/
7423: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7424: {
7426: PetscInt M,N,Ny;
7433: MatCheckPreallocated(A,1);
7434: MatGetSize(A,&M,&N);
7435: VecGetSize(y,&Ny);
7436: if (M == Ny) {
7437: MatMult(A,x,y);
7438: } else {
7439: MatMultTranspose(A,x,y);
7440: }
7441: return(0);
7442: }
7446: /*@
7447: MatRestrict - y = A*x or A'*x
7449: Neighbor-wise Collective on Mat
7451: Input Parameters:
7452: + mat - the matrix
7453: - x,y - the vectors
7455: Level: intermediate
7457: Notes:
7458: This allows one to use either the restriction or interpolation (its transpose)
7459: matrix to do the restriction
7461: Concepts: matrices^restriction
7463: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7465: @*/
7466: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7467: {
7469: PetscInt M,N,Ny;
7476: MatCheckPreallocated(A,1);
7478: MatGetSize(A,&M,&N);
7479: VecGetSize(y,&Ny);
7480: if (M == Ny) {
7481: MatMult(A,x,y);
7482: } else {
7483: MatMultTranspose(A,x,y);
7484: }
7485: return(0);
7486: }
7490: /*@
7491: MatGetNullSpace - retrieves the null space to a matrix.
7493: Logically Collective on Mat and MatNullSpace
7495: Input Parameters:
7496: + mat - the matrix
7497: - nullsp - the null space object
7499: Level: developer
7501: Notes:
7502: This null space is used by solvers. Overwrites any previous null space that may have been attached
7504: Concepts: null space^attaching to matrix
7506: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7507: @*/
7508: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
7509: {
7514: *nullsp = mat->nullsp;
7515: return(0);
7516: }
7520: /*@
7521: MatSetNullSpace - attaches a null space to a matrix.
7522: This null space will be removed from the resulting vector whenever
7523: MatMult() is called
7525: Logically Collective on Mat and MatNullSpace
7527: Input Parameters:
7528: + mat - the matrix
7529: - nullsp - the null space object
7531: Level: advanced
7533: Notes:
7534: This null space is used by solvers. Overwrites any previous null space that may have been attached
7536: Concepts: null space^attaching to matrix
7538: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace()
7539: @*/
7540: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
7541: {
7548: MatCheckPreallocated(mat,1);
7549: PetscObjectReference((PetscObject)nullsp);
7550: MatNullSpaceDestroy(&mat->nullsp);
7552: mat->nullsp = nullsp;
7553: return(0);
7554: }
7558: /*@
7559: MatSetNearNullSpace - attaches a null space to a matrix.
7560: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
7562: Logically Collective on Mat and MatNullSpace
7564: Input Parameters:
7565: + mat - the matrix
7566: - nullsp - the null space object
7568: Level: advanced
7570: Notes:
7571: Overwrites any previous near null space that may have been attached
7573: Concepts: null space^attaching to matrix
7575: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace()
7576: @*/
7577: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
7578: {
7585: MatCheckPreallocated(mat,1);
7586: PetscObjectReference((PetscObject)nullsp);
7587: MatNullSpaceDestroy(&mat->nearnullsp);
7589: mat->nearnullsp = nullsp;
7590: return(0);
7591: }
7595: /*@
7596: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
7598: Not Collective
7600: Input Parameters:
7601: . mat - the matrix
7603: Output Parameters:
7604: . nullsp - the null space object, NULL if not set
7606: Level: developer
7608: Concepts: null space^attaching to matrix
7610: .seealso: MatSetNearNullSpace(), MatGetNullSpace()
7611: @*/
7612: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
7613: {
7618: MatCheckPreallocated(mat,1);
7619: *nullsp = mat->nearnullsp;
7620: return(0);
7621: }
7625: /*@C
7626: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
7628: Collective on Mat
7630: Input Parameters:
7631: + mat - the matrix
7632: . row - row/column permutation
7633: . fill - expected fill factor >= 1.0
7634: - level - level of fill, for ICC(k)
7636: Notes:
7637: Probably really in-place only when level of fill is zero, otherwise allocates
7638: new space to store factored matrix and deletes previous memory.
7640: Most users should employ the simplified KSP interface for linear solvers
7641: instead of working directly with matrix algebra routines such as this.
7642: See, e.g., KSPCreate().
7644: Level: developer
7646: Concepts: matrices^incomplete Cholesky factorization
7647: Concepts: Cholesky factorization
7649: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
7651: Developer Note: fortran interface is not autogenerated as the f90
7652: interface defintion cannot be generated correctly [due to MatFactorInfo]
7654: @*/
7655: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
7656: {
7664: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
7665: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7666: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7667: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7668: MatCheckPreallocated(mat,1);
7669: (*mat->ops->iccfactor)(mat,row,info);
7670: PetscObjectStateIncrease((PetscObject)mat);
7671: return(0);
7672: }
7676: /*@
7677: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
7679: Not Collective
7681: Input Parameters:
7682: + mat - the matrix
7683: . nl - leading dimension of v
7684: - v - the values compute with ADIFOR
7686: Level: developer
7688: Notes:
7689: Must call MatSetColoring() before using this routine. Also this matrix must already
7690: have its nonzero pattern determined.
7692: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
7693: MatSetValues(), MatSetColoring()
7694: @*/
7695: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
7696: {
7704: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7705: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
7706: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7707: (*mat->ops->setvaluesadifor)(mat,nl,v);
7708: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
7709: PetscObjectStateIncrease((PetscObject)mat);
7710: return(0);
7711: }
7715: /*@
7716: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
7717: ghosted ones.
7719: Not Collective
7721: Input Parameters:
7722: + mat - the matrix
7723: - diag = the diagonal values, including ghost ones
7725: Level: developer
7727: Notes: Works only for MPIAIJ and MPIBAIJ matrices
7729: .seealso: MatDiagonalScale()
7730: @*/
7731: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
7732: {
7734: PetscMPIInt size;
7741: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
7742: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
7743: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7744: if (size == 1) {
7745: PetscInt n,m;
7746: VecGetSize(diag,&n);
7747: MatGetSize(mat,0,&m);
7748: if (m == n) {
7749: MatDiagonalScale(mat,0,diag);
7750: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
7751: } else {
7752: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
7753: }
7754: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
7755: PetscObjectStateIncrease((PetscObject)mat);
7756: return(0);
7757: }
7761: /*@
7762: MatGetInertia - Gets the inertia from a factored matrix
7764: Collective on Mat
7766: Input Parameter:
7767: . mat - the matrix
7769: Output Parameters:
7770: + nneg - number of negative eigenvalues
7771: . nzero - number of zero eigenvalues
7772: - npos - number of positive eigenvalues
7774: Level: advanced
7776: Notes: Matrix must have been factored by MatCholeskyFactor()
7779: @*/
7780: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
7781: {
7787: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7788: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
7789: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7790: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
7791: return(0);
7792: }
7794: /* ----------------------------------------------------------------*/
7797: /*@C
7798: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
7800: Neighbor-wise Collective on Mat and Vecs
7802: Input Parameters:
7803: + mat - the factored matrix
7804: - b - the right-hand-side vectors
7806: Output Parameter:
7807: . x - the result vectors
7809: Notes:
7810: The vectors b and x cannot be the same. I.e., one cannot
7811: call MatSolves(A,x,x).
7813: Notes:
7814: Most users should employ the simplified KSP interface for linear solvers
7815: instead of working directly with matrix algebra routines such as this.
7816: See, e.g., KSPCreate().
7818: Level: developer
7820: Concepts: matrices^triangular solves
7822: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
7823: @*/
7824: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
7825: {
7831: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
7832: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
7833: if (!mat->rmap->N && !mat->cmap->N) return(0);
7835: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7836: MatCheckPreallocated(mat,1);
7837: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
7838: (*mat->ops->solves)(mat,b,x);
7839: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
7840: return(0);
7841: }
7845: /*@
7846: MatIsSymmetric - Test whether a matrix is symmetric
7848: Collective on Mat
7850: Input Parameter:
7851: + A - the matrix to test
7852: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
7854: Output Parameters:
7855: . flg - the result
7857: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
7859: Level: intermediate
7861: Concepts: matrix^symmetry
7863: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
7864: @*/
7865: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
7866: {
7873: if (!A->symmetric_set) {
7874: if (!A->ops->issymmetric) {
7875: MatType mattype;
7876: MatGetType(A,&mattype);
7877: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7878: }
7879: (*A->ops->issymmetric)(A,tol,flg);
7880: if (!tol) {
7881: A->symmetric_set = PETSC_TRUE;
7882: A->symmetric = *flg;
7883: if (A->symmetric) {
7884: A->structurally_symmetric_set = PETSC_TRUE;
7885: A->structurally_symmetric = PETSC_TRUE;
7886: }
7887: }
7888: } else if (A->symmetric) {
7889: *flg = PETSC_TRUE;
7890: } else if (!tol) {
7891: *flg = PETSC_FALSE;
7892: } else {
7893: if (!A->ops->issymmetric) {
7894: MatType mattype;
7895: MatGetType(A,&mattype);
7896: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
7897: }
7898: (*A->ops->issymmetric)(A,tol,flg);
7899: }
7900: return(0);
7901: }
7905: /*@
7906: MatIsHermitian - Test whether a matrix is Hermitian
7908: Collective on Mat
7910: Input Parameter:
7911: + A - the matrix to test
7912: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
7914: Output Parameters:
7915: . flg - the result
7917: Level: intermediate
7919: Concepts: matrix^symmetry
7921: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
7922: MatIsSymmetricKnown(), MatIsSymmetric()
7923: @*/
7924: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
7925: {
7932: if (!A->hermitian_set) {
7933: if (!A->ops->ishermitian) {
7934: MatType mattype;
7935: MatGetType(A,&mattype);
7936: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7937: }
7938: (*A->ops->ishermitian)(A,tol,flg);
7939: if (!tol) {
7940: A->hermitian_set = PETSC_TRUE;
7941: A->hermitian = *flg;
7942: if (A->hermitian) {
7943: A->structurally_symmetric_set = PETSC_TRUE;
7944: A->structurally_symmetric = PETSC_TRUE;
7945: }
7946: }
7947: } else if (A->hermitian) {
7948: *flg = PETSC_TRUE;
7949: } else if (!tol) {
7950: *flg = PETSC_FALSE;
7951: } else {
7952: if (!A->ops->ishermitian) {
7953: MatType mattype;
7954: MatGetType(A,&mattype);
7955: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
7956: }
7957: (*A->ops->ishermitian)(A,tol,flg);
7958: }
7959: return(0);
7960: }
7964: /*@
7965: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
7967: Not Collective
7969: Input Parameter:
7970: . A - the matrix to check
7972: Output Parameters:
7973: + set - if the symmetric flag is set (this tells you if the next flag is valid)
7974: - flg - the result
7976: Level: advanced
7978: Concepts: matrix^symmetry
7980: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
7981: if you want it explicitly checked
7983: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
7984: @*/
7985: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
7986: {
7991: if (A->symmetric_set) {
7992: *set = PETSC_TRUE;
7993: *flg = A->symmetric;
7994: } else {
7995: *set = PETSC_FALSE;
7996: }
7997: return(0);
7998: }
8002: /*@
8003: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8005: Not Collective
8007: Input Parameter:
8008: . A - the matrix to check
8010: Output Parameters:
8011: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8012: - flg - the result
8014: Level: advanced
8016: Concepts: matrix^symmetry
8018: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8019: if you want it explicitly checked
8021: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8022: @*/
8023: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8024: {
8029: if (A->hermitian_set) {
8030: *set = PETSC_TRUE;
8031: *flg = A->hermitian;
8032: } else {
8033: *set = PETSC_FALSE;
8034: }
8035: return(0);
8036: }
8040: /*@
8041: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8043: Collective on Mat
8045: Input Parameter:
8046: . A - the matrix to test
8048: Output Parameters:
8049: . flg - the result
8051: Level: intermediate
8053: Concepts: matrix^symmetry
8055: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8056: @*/
8057: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8058: {
8064: if (!A->structurally_symmetric_set) {
8065: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8066: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8068: A->structurally_symmetric_set = PETSC_TRUE;
8069: }
8070: *flg = A->structurally_symmetric;
8071: return(0);
8072: }
8076: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8077: /*@
8078: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8079: to be communicated to other processors during the MatAssemblyBegin/End() process
8081: Not collective
8083: Input Parameter:
8084: . vec - the vector
8086: Output Parameters:
8087: + nstash - the size of the stash
8088: . reallocs - the number of additional mallocs incurred.
8089: . bnstash - the size of the block stash
8090: - breallocs - the number of additional mallocs incurred.in the block stash
8092: Level: advanced
8094: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8096: @*/
8097: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8098: {
8102: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8103: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8104: return(0);
8105: }
8109: /*@C
8110: MatGetVecs - Get vector(s) compatible with the matrix, i.e. with the same
8111: parallel layout
8113: Collective on Mat
8115: Input Parameter:
8116: . mat - the matrix
8118: Output Parameter:
8119: + right - (optional) vector that the matrix can be multiplied against
8120: - left - (optional) vector that the matrix vector product can be stored in
8122: Level: advanced
8124: .seealso: MatCreate()
8125: @*/
8126: PetscErrorCode MatGetVecs(Mat mat,Vec *right,Vec *left)
8127: {
8133: MatCheckPreallocated(mat,1);
8134: if (mat->ops->getvecs) {
8135: (*mat->ops->getvecs)(mat,right,left);
8136: } else {
8137: PetscMPIInt size;
8138: MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
8139: if (right) {
8140: VecCreate(PetscObjectComm((PetscObject)mat),right);
8141: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8142: VecSetBlockSize(*right,mat->rmap->bs);
8143: VecSetType(*right,VECSTANDARD);
8144: PetscLayoutReference(mat->cmap,&(*right)->map);
8145: }
8146: if (left) {
8147: VecCreate(PetscObjectComm((PetscObject)mat),left);
8148: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8149: VecSetBlockSize(*left,mat->rmap->bs);
8150: VecSetType(*left,VECSTANDARD);
8151: PetscLayoutReference(mat->rmap,&(*left)->map);
8152: }
8153: }
8154: return(0);
8155: }
8159: /*@C
8160: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8161: with default values.
8163: Not Collective
8165: Input Parameters:
8166: . info - the MatFactorInfo data structure
8169: Notes: The solvers are generally used through the KSP and PC objects, for example
8170: PCLU, PCILU, PCCHOLESKY, PCICC
8172: Level: developer
8174: .seealso: MatFactorInfo
8176: Developer Note: fortran interface is not autogenerated as the f90
8177: interface defintion cannot be generated correctly [due to MatFactorInfo]
8179: @*/
8181: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8182: {
8186: PetscMemzero(info,sizeof(MatFactorInfo));
8187: return(0);
8188: }
8192: /*@
8193: MatPtAP - Creates the matrix product C = P^T * A * P
8195: Neighbor-wise Collective on Mat
8197: Input Parameters:
8198: + A - the matrix
8199: . P - the projection matrix
8200: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8201: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P))
8203: Output Parameters:
8204: . C - the product matrix
8206: Notes:
8207: C will be created and must be destroyed by the user with MatDestroy().
8209: This routine is currently only implemented for pairs of AIJ matrices and classes
8210: which inherit from AIJ.
8212: Level: intermediate
8214: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
8215: @*/
8216: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
8217: {
8219: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8220: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
8221: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8222: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
8225: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
8226: PetscOptionsGetBool(((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
8230: MatCheckPreallocated(A,1);
8231: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8232: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8235: MatCheckPreallocated(P,2);
8236: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8237: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8239: 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);
8240: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8242: if (scall == MAT_REUSE_MATRIX) {
8245: if (viatranspose || viamatmatmatmult) {
8246: Mat Pt;
8247: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8248: if (viamatmatmatmult) {
8249: MatMatMatMult(Pt,A,P,scall,fill,C);
8250: } else {
8251: Mat AP;
8252: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8253: MatMatMult(Pt,AP,scall,fill,C);
8254: MatDestroy(&AP);
8255: }
8256: MatDestroy(&Pt);
8257: } else {
8258: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8259: (*(*C)->ops->ptapnumeric)(A,P,*C);
8260: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8261: }
8262: return(0);
8263: }
8265: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8266: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8268: fA = A->ops->ptap;
8269: fP = P->ops->ptap;
8270: if (fP == fA) {
8271: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
8272: ptap = fA;
8273: } else {
8274: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
8275: char ptapname[256];
8276: PetscStrcpy(ptapname,"MatPtAP_");
8277: PetscStrcat(ptapname,((PetscObject)A)->type_name);
8278: PetscStrcat(ptapname,"_");
8279: PetscStrcat(ptapname,((PetscObject)P)->type_name);
8280: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
8281: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
8282: 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);
8283: }
8285: if (viatranspose || viamatmatmatmult) {
8286: Mat Pt;
8287: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
8288: if (viamatmatmatmult) {
8289: MatMatMatMult(Pt,A,P,scall,fill,C);
8290: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
8291: } else {
8292: Mat AP;
8293: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
8294: MatMatMult(Pt,AP,scall,fill,C);
8295: MatDestroy(&AP);
8296: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
8297: }
8298: MatDestroy(&Pt);
8299: } else {
8300: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
8301: (*ptap)(A,P,scall,fill,C);
8302: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
8303: }
8304: return(0);
8305: }
8309: /*@
8310: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
8312: Neighbor-wise Collective on Mat
8314: Input Parameters:
8315: + A - the matrix
8316: - P - the projection matrix
8318: Output Parameters:
8319: . C - the product matrix
8321: Notes:
8322: C must have been created by calling MatPtAPSymbolic and must be destroyed by
8323: the user using MatDeatroy().
8325: This routine is currently only implemented for pairs of AIJ matrices and classes
8326: which inherit from AIJ. C will be of type MATAIJ.
8328: Level: intermediate
8330: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
8331: @*/
8332: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
8333: {
8339: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8340: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8343: MatCheckPreallocated(P,2);
8344: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8345: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8348: MatCheckPreallocated(C,3);
8349: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8350: 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);
8351: 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);
8352: 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);
8353: 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);
8354: MatCheckPreallocated(A,1);
8356: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
8357: (*C->ops->ptapnumeric)(A,P,C);
8358: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
8359: return(0);
8360: }
8364: /*@
8365: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
8367: Neighbor-wise Collective on Mat
8369: Input Parameters:
8370: + A - the matrix
8371: - P - the projection matrix
8373: Output Parameters:
8374: . C - the (i,j) structure of the product matrix
8376: Notes:
8377: C will be created and must be destroyed by the user with MatDestroy().
8379: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8380: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8381: this (i,j) structure by calling MatPtAPNumeric().
8383: Level: intermediate
8385: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
8386: @*/
8387: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
8388: {
8394: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8395: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8396: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8399: MatCheckPreallocated(P,2);
8400: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8401: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8404: 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);
8405: 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);
8406: MatCheckPreallocated(A,1);
8407: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
8408: (*A->ops->ptapsymbolic)(A,P,fill,C);
8409: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
8411: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
8412: return(0);
8413: }
8417: /*@
8418: MatRARt - Creates the matrix product C = R * A * R^T
8420: Neighbor-wise Collective on Mat
8422: Input Parameters:
8423: + A - the matrix
8424: . R - the projection matrix
8425: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8426: - fill - expected fill as ratio of nnz(C)/nnz(A)
8428: Output Parameters:
8429: . C - the product matrix
8431: Notes:
8432: C will be created and must be destroyed by the user with MatDestroy().
8434: This routine is currently only implemented for pairs of AIJ matrices and classes
8435: which inherit from AIJ.
8437: Level: intermediate
8439: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
8440: @*/
8441: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
8442: {
8448: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8449: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8452: MatCheckPreallocated(R,2);
8453: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8454: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8456: 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);
8457: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8458: MatCheckPreallocated(A,1);
8460: if (!A->ops->rart) {
8461: MatType mattype;
8462: MatGetType(A,&mattype);
8463: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
8464: }
8465: PetscLogEventBegin(MAT_RARt,A,R,0,0);
8466: (*A->ops->rart)(A,R,scall,fill,C);
8467: PetscLogEventEnd(MAT_RARt,A,R,0,0);
8468: return(0);
8469: }
8473: /*@
8474: MatRARtNumeric - Computes the matrix product C = R * A * R^T
8476: Neighbor-wise Collective on Mat
8478: Input Parameters:
8479: + A - the matrix
8480: - R - the projection matrix
8482: Output Parameters:
8483: . C - the product matrix
8485: Notes:
8486: C must have been created by calling MatRARtSymbolic and must be destroyed by
8487: the user using MatDeatroy().
8489: This routine is currently only implemented for pairs of AIJ matrices and classes
8490: which inherit from AIJ. C will be of type MATAIJ.
8492: Level: intermediate
8494: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
8495: @*/
8496: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
8497: {
8503: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8504: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8507: MatCheckPreallocated(R,2);
8508: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8509: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8512: MatCheckPreallocated(C,3);
8513: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8514: 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);
8515: 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);
8516: 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);
8517: 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);
8518: MatCheckPreallocated(A,1);
8520: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
8521: (*A->ops->rartnumeric)(A,R,C);
8522: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
8523: return(0);
8524: }
8528: /*@
8529: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
8531: Neighbor-wise Collective on Mat
8533: Input Parameters:
8534: + A - the matrix
8535: - R - the projection matrix
8537: Output Parameters:
8538: . C - the (i,j) structure of the product matrix
8540: Notes:
8541: C will be created and must be destroyed by the user with MatDestroy().
8543: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
8544: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
8545: this (i,j) structure by calling MatRARtNumeric().
8547: Level: intermediate
8549: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
8550: @*/
8551: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
8552: {
8558: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8559: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8560: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8563: MatCheckPreallocated(R,2);
8564: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8565: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8568: 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);
8569: 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);
8570: MatCheckPreallocated(A,1);
8571: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
8572: (*A->ops->rartsymbolic)(A,R,fill,C);
8573: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
8575: MatSetBlockSize(*C,A->rmap->bs);
8576: return(0);
8577: }
8581: /*@
8582: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
8584: Neighbor-wise Collective on Mat
8586: Input Parameters:
8587: + A - the left matrix
8588: . B - the right matrix
8589: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8590: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
8591: if the result is a dense matrix this is irrelevent
8593: Output Parameters:
8594: . C - the product matrix
8596: Notes:
8597: Unless scall is MAT_REUSE_MATRIX C will be created.
8599: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8601: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8602: actually needed.
8604: If you have many matrices with the same non-zero structure to multiply, you
8605: should either
8606: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8607: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
8609: Level: intermediate
8611: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
8612: @*/
8613: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8614: {
8616: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8617: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8618: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8623: MatCheckPreallocated(A,1);
8624: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8625: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8628: MatCheckPreallocated(B,2);
8629: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8630: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8632: 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);
8633: if (scall == MAT_REUSE_MATRIX) {
8636: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8637: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
8638: (*(*C)->ops->matmultnumeric)(A,B,*C);
8639: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
8640: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8641: return(0);
8642: }
8643: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8644: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8646: fA = A->ops->matmult;
8647: fB = B->ops->matmult;
8648: if (fB == fA) {
8649: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8650: mult = fB;
8651: } else {
8652: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
8653: char multname[256];
8654: PetscStrcpy(multname,"MatMatMult_");
8655: PetscStrcat(multname,((PetscObject)A)->type_name);
8656: PetscStrcat(multname,"_");
8657: PetscStrcat(multname,((PetscObject)B)->type_name);
8658: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
8659: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
8660: 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);
8661: }
8662: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
8663: (*mult)(A,B,scall,fill,C);
8664: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
8665: return(0);
8666: }
8670: /*@
8671: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
8672: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
8674: Neighbor-wise Collective on Mat
8676: Input Parameters:
8677: + A - the left matrix
8678: . B - the right matrix
8679: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
8680: if C is a dense matrix this is irrelevent
8682: Output Parameters:
8683: . C - the product matrix
8685: Notes:
8686: Unless scall is MAT_REUSE_MATRIX C will be created.
8688: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8689: actually needed.
8691: This routine is currently implemented for
8692: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
8693: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8694: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8696: Level: intermediate
8698: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
8699: We should incorporate them into PETSc.
8701: .seealso: MatMatMult(), MatMatMultNumeric()
8702: @*/
8703: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
8704: {
8706: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
8707: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
8708: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
8713: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8714: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8718: MatCheckPreallocated(B,2);
8719: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8720: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8723: 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);
8724: if (fill == PETSC_DEFAULT) fill = 2.0;
8725: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8726: MatCheckPreallocated(A,1);
8728: Asymbolic = A->ops->matmultsymbolic;
8729: Bsymbolic = B->ops->matmultsymbolic;
8730: if (Asymbolic == Bsymbolic) {
8731: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
8732: symbolic = Bsymbolic;
8733: } else { /* dispatch based on the type of A and B */
8734: char symbolicname[256];
8735: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
8736: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
8737: PetscStrcat(symbolicname,"_");
8738: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
8739: PetscStrcat(symbolicname,"_C");
8740: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
8741: 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);
8742: }
8743: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
8744: (*symbolic)(A,B,fill,C);
8745: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
8746: return(0);
8747: }
8751: /*@
8752: MatMatMultNumeric - Performs the numeric matrix-matrix product.
8753: Call this routine after first calling MatMatMultSymbolic().
8755: Neighbor-wise Collective on Mat
8757: Input Parameters:
8758: + A - the left matrix
8759: - B - the right matrix
8761: Output Parameters:
8762: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
8764: Notes:
8765: C must have been created with MatMatMultSymbolic().
8767: This routine is currently implemented for
8768: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
8769: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
8770: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
8772: Level: intermediate
8774: .seealso: MatMatMult(), MatMatMultSymbolic()
8775: @*/
8776: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
8777: {
8781: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
8782: return(0);
8783: }
8787: /*@
8788: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
8790: Neighbor-wise Collective on Mat
8792: Input Parameters:
8793: + A - the left matrix
8794: . B - the right matrix
8795: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8796: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8798: Output Parameters:
8799: . C - the product matrix
8801: Notes:
8802: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8804: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8806: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8807: actually needed.
8809: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
8811: Level: intermediate
8813: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
8814: @*/
8815: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8816: {
8818: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8819: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8824: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8825: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8828: MatCheckPreallocated(B,2);
8829: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8830: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8832: 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);
8833: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8834: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8835: MatCheckPreallocated(A,1);
8837: fA = A->ops->mattransposemult;
8838: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
8839: fB = B->ops->mattransposemult;
8840: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
8841: 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);
8843: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
8844: if (scall == MAT_INITIAL_MATRIX) {
8845: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
8846: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
8847: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
8848: }
8849: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
8850: (*A->ops->mattransposemultnumeric)(A,B,*C);
8851: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
8852: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
8853: return(0);
8854: }
8858: /*@
8859: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
8861: Neighbor-wise Collective on Mat
8863: Input Parameters:
8864: + A - the left matrix
8865: . B - the right matrix
8866: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8867: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
8869: Output Parameters:
8870: . C - the product matrix
8872: Notes:
8873: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
8875: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
8877: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8878: actually needed.
8880: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
8881: which inherit from SeqAIJ. C will be of same type as the input matrices.
8883: Level: intermediate
8885: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
8886: @*/
8887: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
8888: {
8890: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
8891: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
8892: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
8897: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8898: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8901: MatCheckPreallocated(B,2);
8902: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8903: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8905: 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);
8906: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8907: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be > 1.0",fill);
8908: MatCheckPreallocated(A,1);
8910: fA = A->ops->transposematmult;
8911: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
8912: fB = B->ops->transposematmult;
8913: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for B of type %s",((PetscObject)B)->type_name);
8914: if (fB==fA) {
8915: transposematmult = fA;
8916: }
8917: 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);
8918: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
8919: (*transposematmult)(A,B,scall,fill,C);
8920: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
8921: return(0);
8922: }
8926: /*@
8927: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
8929: Neighbor-wise Collective on Mat
8931: Input Parameters:
8932: + A - the left matrix
8933: . B - the middle matrix
8934: . C - the right matrix
8935: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
8936: - 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
8937: if the result is a dense matrix this is irrelevent
8939: Output Parameters:
8940: . D - the product matrix
8942: Notes:
8943: Unless scall is MAT_REUSE_MATRIX D will be created.
8945: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
8947: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
8948: actually needed.
8950: If you have many matrices with the same non-zero structure to multiply, you
8951: should either
8952: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
8953: $ 2) call MatMatMatMultSymbolic() once and then MatMatMatMultNumeric() for each product needed
8955: Level: intermediate
8957: .seealso: MatMatMult, MatPtAP()
8958: @*/
8959: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
8960: {
8962: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8963: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8964: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
8965: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
8970: MatCheckPreallocated(A,1);
8971: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8972: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8975: MatCheckPreallocated(B,2);
8976: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8977: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8980: MatCheckPreallocated(C,3);
8981: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8982: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8983: 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);
8984: 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);
8985: if (scall == MAT_REUSE_MATRIX) {
8988: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
8989: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
8990: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
8991: return(0);
8992: }
8993: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
8994: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%G must be >= 1.0",fill);
8996: fA = A->ops->matmatmult;
8997: fB = B->ops->matmatmult;
8998: fC = C->ops->matmatmult;
8999: if (fA == fB && fA == fC) {
9000: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9001: mult = fA;
9002: } else {
9003: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9004: char multname[256];
9005: PetscStrcpy(multname,"MatMatMatMult_");
9006: PetscStrcat(multname,((PetscObject)A)->type_name);
9007: PetscStrcat(multname,"_");
9008: PetscStrcat(multname,((PetscObject)B)->type_name);
9009: PetscStrcat(multname,"_");
9010: PetscStrcat(multname,((PetscObject)C)->type_name);
9011: PetscStrcat(multname,"_C");
9012: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9013: 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);
9014: }
9015: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9016: (*mult)(A,B,C,scall,fill,D);
9017: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9018: return(0);
9019: }
9023: /*@C
9024: MatGetRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9026: Collective on Mat
9028: Input Parameters:
9029: + mat - the matrix
9030: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9031: . subcomm - MPI communicator split from the communicator where mat resides in
9032: . mlocal_red - number of local rows of the redundant matrix
9033: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9035: Output Parameter:
9036: . matredundant - redundant matrix
9038: Notes:
9039: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9040: original matrix has not changed from that last call to MatGetRedundantMatrix().
9042: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9043: calling it.
9045: Only MPIAIJ matrix is supported.
9047: Level: advanced
9049: Concepts: subcommunicator
9050: Concepts: duplicate matrix
9052: .seealso: MatDestroy()
9053: @*/
9054: PetscErrorCode MatGetRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,PetscInt mlocal_red,MatReuse reuse,Mat *matredundant)
9055: {
9060: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9063: }
9064: if (!mat->ops->getredundantmatrix) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
9065: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9066: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9067: MatCheckPreallocated(mat,1);
9069: PetscLogEventBegin(MAT_GetRedundantMatrix,mat,0,0,0);
9070: (*mat->ops->getredundantmatrix)(mat,nsubcomm,subcomm,mlocal_red,reuse,matredundant);
9071: PetscLogEventEnd(MAT_GetRedundantMatrix,mat,0,0,0);
9072: return(0);
9073: }
9077: /*@C
9078: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
9079: a given 'mat' object. Each submatrix can span multiple procs.
9081: Collective on Mat
9083: Input Parameters:
9084: + mat - the matrix
9085: . subcomm - the subcommunicator obtained by com_split(comm)
9086: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9088: Output Parameter:
9089: . subMat - 'parallel submatrices each spans a given subcomm
9091: Notes:
9092: The submatrix partition across processors is dictated by 'subComm' a
9093: communicator obtained by com_split(comm). The comm_split
9094: is not restriced to be grouped with consecutive original ranks.
9096: Due the comm_split() usage, the parallel layout of the submatrices
9097: map directly to the layout of the original matrix [wrt the local
9098: row,col partitioning]. So the original 'DiagonalMat' naturally maps
9099: into the 'DiagonalMat' of the subMat, hence it is used directly from
9100: the subMat. However the offDiagMat looses some columns - and this is
9101: reconstructed with MatSetValues()
9103: Level: advanced
9105: Concepts: subcommunicator
9106: Concepts: submatrices
9108: .seealso: MatGetSubMatrices()
9109: @*/
9110: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
9111: {
9113: PetscMPIInt commsize,subCommSize;
9116: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
9117: MPI_Comm_size(subComm,&subCommSize);
9118: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
9120: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
9121: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
9122: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
9123: return(0);
9124: }
9128: /*@
9129: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
9131: Not Collective
9133: Input Arguments:
9134: mat - matrix to extract local submatrix from
9135: isrow - local row indices for submatrix
9136: iscol - local column indices for submatrix
9138: Output Arguments:
9139: submat - the submatrix
9141: Level: intermediate
9143: Notes:
9144: The submat should be returned with MatRestoreLocalSubMatrix().
9146: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
9147: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
9149: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
9150: MatSetValuesBlockedLocal() will also be implemented.
9152: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef()
9153: @*/
9154: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9155: {
9165: if (mat->ops->getlocalsubmatrix) {
9166: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
9167: } else {
9168: MatCreateLocalRef(mat,isrow,iscol,submat);
9169: }
9170: return(0);
9171: }
9175: /*@
9176: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
9178: Not Collective
9180: Input Arguments:
9181: mat - matrix to extract local submatrix from
9182: isrow - local row indices for submatrix
9183: iscol - local column indices for submatrix
9184: submat - the submatrix
9186: Level: intermediate
9188: .seealso: MatGetLocalSubMatrix()
9189: @*/
9190: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
9191: {
9200: if (*submat) {
9202: }
9204: if (mat->ops->restorelocalsubmatrix) {
9205: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
9206: } else {
9207: MatDestroy(submat);
9208: }
9209: *submat = NULL;
9210: return(0);
9211: }
9213: /* --------------------------------------------------------*/
9216: /*@
9217: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
9219: Collective on Mat
9221: Input Parameter:
9222: . mat - the matrix
9224: Output Parameter:
9225: . is - if any rows have zero diagonals this contains the list of them
9227: Level: developer
9229: Concepts: matrix-vector product
9231: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
9232: @*/
9233: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
9234: {
9240: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9241: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9243: if (!mat->ops->findzerodiagonals) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find zero diagonals defined");
9244: (*mat->ops->findzerodiagonals)(mat,is);
9245: return(0);
9246: }
9250: /*@C
9251: MatInvertBlockDiagonal - Inverts the block diagonal entries.
9253: Collective on Mat
9255: Input Parameters:
9256: . mat - the matrix
9258: Output Parameters:
9259: . values - the block inverses in column major order (FORTRAN-like)
9261: Note:
9262: This routine is not available from Fortran.
9264: Level: advanced
9265: @*/
9266: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
9267: {
9272: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9273: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9274: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
9275: (*mat->ops->invertblockdiagonal)(mat,values);
9276: return(0);
9277: }
9281: /*@C
9282: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
9283: via MatTransposeColoringCreate().
9285: Collective on MatTransposeColoring
9287: Input Parameter:
9288: . c - coloring context
9290: Level: intermediate
9292: .seealso: MatTransposeColoringCreate()
9293: @*/
9294: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
9295: {
9296: PetscErrorCode ierr;
9297: MatTransposeColoring matcolor=*c;
9300: if (!matcolor) return(0);
9301: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
9303: PetscFree(matcolor->ncolumns);
9304: PetscFree(matcolor->nrows);
9305: PetscFree(matcolor->colorforrow);
9306: PetscFree2(matcolor->rows,matcolor->columnsforspidx);
9307: PetscFree(matcolor->colorforcol);
9308: PetscFree(matcolor->columns);
9309: PetscHeaderDestroy(c);
9310: return(0);
9311: }
9315: /*@C
9316: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
9317: a MatTransposeColoring context has been created, computes a dense B^T by Apply
9318: MatTransposeColoring to sparse B.
9320: Collective on MatTransposeColoring
9322: Input Parameters:
9323: + B - sparse matrix B
9324: . Btdense - symbolic dense matrix B^T
9325: - coloring - coloring context created with MatTransposeColoringCreate()
9327: Output Parameter:
9328: . Btdense - dense matrix B^T
9330: Options Database Keys:
9331: + -mat_transpose_coloring_view - Activates basic viewing or coloring
9332: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
9333: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
9335: Level: intermediate
9337: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
9339: .keywords: coloring
9340: @*/
9341: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
9342: {
9350: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
9351: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
9352: return(0);
9353: }
9357: /*@C
9358: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
9359: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
9360: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
9361: Csp from Cden.
9363: Collective on MatTransposeColoring
9365: Input Parameters:
9366: + coloring - coloring context created with MatTransposeColoringCreate()
9367: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
9369: Output Parameter:
9370: . Csp - sparse matrix
9372: Options Database Keys:
9373: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
9374: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
9375: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
9377: Level: intermediate
9379: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
9381: .keywords: coloring
9382: @*/
9383: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
9384: {
9392: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
9393: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
9394: return(0);
9395: }
9399: /*@C
9400: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
9402: Collective on Mat
9404: Input Parameters:
9405: + mat - the matrix product C
9406: - iscoloring - the coloring of the matrix; usually obtained with MatGetColoring() or DMCreateColoring()
9408: Output Parameter:
9409: . color - the new coloring context
9411: Level: intermediate
9413: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
9414: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
9415: @*/
9416: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
9417: {
9418: MatTransposeColoring c;
9419: MPI_Comm comm;
9420: PetscErrorCode ierr;
9423: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
9424: PetscObjectGetComm((PetscObject)mat,&comm);
9425: PetscHeaderCreate(c,_p_MatTransposeColoring,int,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,0);
9427: c->ctype = iscoloring->ctype;
9428: if (mat->ops->transposecoloringcreate) {
9429: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
9430: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
9432: *color = c;
9433: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
9434: return(0);
9435: }