Actual source code: matrix.c
petsc-3.8.0 2017-09-26
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc/private/matimpl.h>
7: #include <petsc/private/isimpl.h>
8: #include <petsc/private/vecimpl.h>
10: /* Logging support */
11: PetscClassId MAT_CLASSID;
12: PetscClassId MAT_COLORING_CLASSID;
13: PetscClassId MAT_FDCOLORING_CLASSID;
14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_CreateSubMats, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_CreateSubMat;
24: PetscLogEvent MAT_TransposeColoringCreate;
25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34: PetscLogEvent MAT_GetMultiProcBlock;
35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36: PetscLogEvent MAT_ViennaCLCopyToGPU;
37: PetscLogEvent MAT_Merge,MAT_Residual,MAT_SetRandom;
38: PetscLogEvent MATCOLORING_Apply,MATCOLORING_Comm,MATCOLORING_Local,MATCOLORING_ISCreate,MATCOLORING_SetUp,MATCOLORING_Weights;
40: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
42: /*@
43: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
45: Logically Collective on Vec
47: Input Parameters:
48: + x - the vector
49: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
50: it will create one internally.
52: Output Parameter:
53: . x - the vector
55: Example of Usage:
56: .vb
57: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
58: MatSetRandom(x,rctx);
59: PetscRandomDestroy(rctx);
60: .ve
62: Level: intermediate
64: Concepts: matrix^setting to random
65: Concepts: random^matrix
67: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
68: @*/
69: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
70: {
72: PetscRandom randObj = NULL;
79: if (!rctx) {
80: MPI_Comm comm;
81: PetscObjectGetComm((PetscObject)x,&comm);
82: PetscRandomCreate(comm,&randObj);
83: PetscRandomSetFromOptions(randObj);
84: rctx = randObj;
85: }
87: PetscLogEventBegin(MAT_SetRandom,x,rctx,0,0);
88: (*x->ops->setrandom)(x,rctx);
89: PetscLogEventEnd(MAT_SetRandom,x,rctx,0,0);
91: x->assembled = PETSC_TRUE;
92: PetscRandomDestroy(&randObj);
93: return(0);
94: }
96: /*@
97: MatFactorGetErrorZeroPivot - returns the pivot value that was determined to be zero and the row it occurred in
99: Logically Collective on Mat
101: Input Parameters:
102: . mat - the factored matrix
104: Output Parameter:
105: + pivot - the pivot value computed
106: - row - the row that the zero pivot occurred. Note that this row must be interpreted carefully due to row reorderings and which processes
107: the share the matrix
109: Level: advanced
111: Notes: This routine does not work for factorizations done with external packages.
112: This routine should only be called if MatGetFactorError() returns a value of MAT_FACTOR_NUMERIC_ZEROPIVOT
114: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
116: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
117: @*/
118: PetscErrorCode MatFactorGetErrorZeroPivot(Mat mat,PetscReal *pivot,PetscInt *row)
119: {
122: *pivot = mat->factorerror_zeropivot_value;
123: *row = mat->factorerror_zeropivot_row;
124: return(0);
125: }
127: /*@
128: MatFactorGetError - gets the error code from a factorization
130: Logically Collective on Mat
132: Input Parameters:
133: . mat - the factored matrix
135: Output Parameter:
136: . err - the error code
138: Level: advanced
140: Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
142: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorClearError(), MatFactorGetErrorZeroPivot()
143: @*/
144: PetscErrorCode MatFactorGetError(Mat mat,MatFactorError *err)
145: {
148: *err = mat->factorerrortype;
149: return(0);
150: }
152: /*@
153: MatFactorClearError - clears the error code in a factorization
155: Logically Collective on Mat
157: Input Parameter:
158: . mat - the factored matrix
160: Level: developer
162: Notes: This can be called on non-factored matrices that come from, for example, matrices used in SOR.
164: .seealso: MatZeroEntries(), MatFactor(), MatGetFactor(), MatFactorSymbolic(), MatFactorGetError(), MatFactorGetErrorZeroPivot()
165: @*/
166: PetscErrorCode MatFactorClearError(Mat mat)
167: {
170: mat->factorerrortype = MAT_FACTOR_NOERROR;
171: mat->factorerror_zeropivot_value = 0.0;
172: mat->factorerror_zeropivot_row = 0;
173: return(0);
174: }
177: /*@
178: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
180: Input Parameter:
181: . A - the matrix
183: Output Parameter:
184: . keptrows - the rows that are not completely zero
186: Notes: keptrows is set to NULL if all rows are nonzero.
188: Level: intermediate
190: @*/
191: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
192: {
197: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
198: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
199: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
200: (*mat->ops->findnonzerorows)(mat,keptrows);
201: return(0);
202: }
204: /*@
205: MatFindZeroRows - Locate all rows that are completely zero in the matrix
207: Input Parameter:
208: . A - the matrix
210: Output Parameter:
211: . zerorows - the rows that are completely zero
213: Notes: zerorows is set to NULL if no rows are zero.
215: Level: intermediate
217: @*/
218: PetscErrorCode MatFindZeroRows(Mat mat,IS *zerorows)
219: {
221: IS keptrows;
222: PetscInt m, n;
227: MatFindNonzeroRows(mat, &keptrows);
228: /* MatFindNonzeroRows sets keptrows to NULL if there are no zero rows.
229: In keeping with this convention, we set zerorows to NULL if there are no zero
230: rows. */
231: if (keptrows == NULL) {
232: *zerorows = NULL;
233: } else {
234: MatGetOwnershipRange(mat,&m,&n);
235: ISComplement(keptrows,m,n,zerorows);
236: ISDestroy(&keptrows);
237: }
238: return(0);
239: }
241: /*@
242: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
244: Not Collective
246: Input Parameters:
247: . A - the matrix
249: Output Parameters:
250: . a - the diagonal part (which is a SEQUENTIAL matrix)
252: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
253: Use caution, as the reference count on the returned matrix is not incremented and it is used as
254: part of the containing MPI Mat's normal operation.
256: Level: advanced
258: @*/
259: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
260: {
267: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
268: if (!A->ops->getdiagonalblock) {
269: PetscMPIInt size;
270: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
271: if (size == 1) {
272: *a = A;
273: return(0);
274: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Not coded for this matrix type");
275: }
276: (*A->ops->getdiagonalblock)(A,a);
277: return(0);
278: }
280: /*@
281: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
283: Collective on Mat
285: Input Parameters:
286: . mat - the matrix
288: Output Parameter:
289: . trace - the sum of the diagonal entries
291: Level: advanced
293: @*/
294: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
295: {
297: Vec diag;
300: MatCreateVecs(mat,&diag,NULL);
301: MatGetDiagonal(mat,diag);
302: VecSum(diag,trace);
303: VecDestroy(&diag);
304: return(0);
305: }
307: /*@
308: MatRealPart - Zeros out the imaginary part of the matrix
310: Logically Collective on Mat
312: Input Parameters:
313: . mat - the matrix
315: Level: advanced
318: .seealso: MatImaginaryPart()
319: @*/
320: PetscErrorCode MatRealPart(Mat mat)
321: {
327: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
328: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
329: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
330: MatCheckPreallocated(mat,1);
331: (*mat->ops->realpart)(mat);
332: #if defined(PETSC_HAVE_CUSP)
333: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
334: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
335: }
336: #elif defined(PETSC_HAVE_VIENNACL)
337: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
338: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
339: }
340: #elif defined(PETSC_HAVE_VECCUDA)
341: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
342: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
343: }
344: #endif
345: return(0);
346: }
348: /*@C
349: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
351: Collective on Mat
353: Input Parameter:
354: . mat - the matrix
356: Output Parameters:
357: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
358: - ghosts - the global indices of the ghost points
360: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
362: Level: advanced
364: @*/
365: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
366: {
372: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
373: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
374: if (!mat->ops->getghosts) {
375: if (nghosts) *nghosts = 0;
376: if (ghosts) *ghosts = 0;
377: } else {
378: (*mat->ops->getghosts)(mat,nghosts,ghosts);
379: }
380: return(0);
381: }
384: /*@
385: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
387: Logically Collective on Mat
389: Input Parameters:
390: . mat - the matrix
392: Level: advanced
395: .seealso: MatRealPart()
396: @*/
397: PetscErrorCode MatImaginaryPart(Mat mat)
398: {
404: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
405: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
406: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
407: MatCheckPreallocated(mat,1);
408: (*mat->ops->imaginarypart)(mat);
409: #if defined(PETSC_HAVE_CUSP)
410: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
411: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
412: }
413: #elif defined(PETSC_HAVE_VIENNACL)
414: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
415: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
416: }
417: #elif defined(PETSC_HAVE_VECCUDA)
418: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
419: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
420: }
421: #endif
422: return(0);
423: }
425: /*@
426: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
428: Not Collective
430: Input Parameter:
431: . mat - the matrix
433: Output Parameters:
434: + missing - is any diagonal missing
435: - dd - first diagonal entry that is missing (optional) on this process
437: Level: advanced
440: .seealso: MatRealPart()
441: @*/
442: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
443: {
449: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
450: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
451: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
452: (*mat->ops->missingdiagonal)(mat,missing,dd);
453: return(0);
454: }
456: /*@C
457: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
458: for each row that you get to ensure that your application does
459: not bleed memory.
461: Not Collective
463: Input Parameters:
464: + mat - the matrix
465: - row - the row to get
467: Output Parameters:
468: + ncols - if not NULL, the number of nonzeros in the row
469: . cols - if not NULL, the column numbers
470: - vals - if not NULL, the values
472: Notes:
473: This routine is provided for people who need to have direct access
474: to the structure of a matrix. We hope that we provide enough
475: high-level matrix routines that few users will need it.
477: MatGetRow() always returns 0-based column indices, regardless of
478: whether the internal representation is 0-based (default) or 1-based.
480: For better efficiency, set cols and/or vals to NULL if you do
481: not wish to extract these quantities.
483: The user can only examine the values extracted with MatGetRow();
484: the values cannot be altered. To change the matrix entries, one
485: must use MatSetValues().
487: You can only have one call to MatGetRow() outstanding for a particular
488: matrix at a time, per processor. MatGetRow() can only obtain rows
489: associated with the given processor, it cannot get rows from the
490: other processors; for that we suggest using MatCreateSubMatrices(), then
491: MatGetRow() on the submatrix. The row index passed to MatGetRows()
492: is in the global number of rows.
494: Fortran Notes:
495: The calling sequence from Fortran is
496: .vb
497: MatGetRow(matrix,row,ncols,cols,values,ierr)
498: Mat matrix (input)
499: integer row (input)
500: integer ncols (output)
501: integer cols(maxcols) (output)
502: double precision (or double complex) values(maxcols) output
503: .ve
504: where maxcols >= maximum nonzeros in any row of the matrix.
507: Caution:
508: Do not try to change the contents of the output arrays (cols and vals).
509: In some cases, this may corrupt the matrix.
511: Level: advanced
513: Concepts: matrices^row access
515: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatCreateSubMatrices(), MatGetDiagonal()
516: @*/
517: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
518: {
520: PetscInt incols;
525: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
526: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
527: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
528: MatCheckPreallocated(mat,1);
529: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
530: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
531: if (ncols) *ncols = incols;
532: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
533: return(0);
534: }
536: /*@
537: MatConjugate - replaces the matrix values with their complex conjugates
539: Logically Collective on Mat
541: Input Parameters:
542: . mat - the matrix
544: Level: advanced
546: .seealso: VecConjugate()
547: @*/
548: PetscErrorCode MatConjugate(Mat mat)
549: {
550: #if defined(PETSC_USE_COMPLEX)
555: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
556: 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");
557: (*mat->ops->conjugate)(mat);
558: #if defined(PETSC_HAVE_CUSP)
559: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
560: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
561: }
562: #elif defined(PETSC_HAVE_VIENNACL)
563: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
564: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
565: }
566: #elif defined(PETSC_HAVE_VECCUDA)
567: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
568: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
569: }
570: #endif
571: return(0);
572: #else
573: return 0;
574: #endif
575: }
577: /*@C
578: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
580: Not Collective
582: Input Parameters:
583: + mat - the matrix
584: . row - the row to get
585: . ncols, cols - the number of nonzeros and their columns
586: - vals - if nonzero the column values
588: Notes:
589: This routine should be called after you have finished examining the entries.
591: This routine zeros out ncols, cols, and vals. This is to prevent accidental
592: us of the array after it has been restored. If you pass NULL, it will
593: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
595: Fortran Notes:
596: The calling sequence from Fortran is
597: .vb
598: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
599: Mat matrix (input)
600: integer row (input)
601: integer ncols (output)
602: integer cols(maxcols) (output)
603: double precision (or double complex) values(maxcols) output
604: .ve
605: Where maxcols >= maximum nonzeros in any row of the matrix.
607: In Fortran MatRestoreRow() MUST be called after MatGetRow()
608: before another call to MatGetRow() can be made.
610: Level: advanced
612: .seealso: MatGetRow()
613: @*/
614: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
615: {
621: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
622: if (!mat->ops->restorerow) return(0);
623: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
624: if (ncols) *ncols = 0;
625: if (cols) *cols = NULL;
626: if (vals) *vals = NULL;
627: return(0);
628: }
630: /*@
631: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
632: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
634: Not Collective
636: Input Parameters:
637: + mat - the matrix
639: Notes:
640: 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.
642: Level: advanced
644: Concepts: matrices^row access
646: .seealso: MatRestoreRowRowUpperTriangular()
647: @*/
648: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
649: {
655: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
656: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
657: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
658: MatCheckPreallocated(mat,1);
659: (*mat->ops->getrowuppertriangular)(mat);
660: return(0);
661: }
663: /*@
664: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
666: Not Collective
668: Input Parameters:
669: + mat - the matrix
671: Notes:
672: This routine should be called after you have finished MatGetRow/MatRestoreRow().
675: Level: advanced
677: .seealso: MatGetRowUpperTriangular()
678: @*/
679: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
680: {
685: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
686: if (!mat->ops->restorerowuppertriangular) return(0);
687: (*mat->ops->restorerowuppertriangular)(mat);
688: return(0);
689: }
691: /*@C
692: MatSetOptionsPrefix - Sets the prefix used for searching for all
693: Mat options in the database.
695: Logically Collective on Mat
697: Input Parameter:
698: + A - the Mat context
699: - prefix - the prefix to prepend to all option names
701: Notes:
702: A hyphen (-) must NOT be given at the beginning of the prefix name.
703: The first character of all runtime options is AUTOMATICALLY the hyphen.
705: Level: advanced
707: .keywords: Mat, set, options, prefix, database
709: .seealso: MatSetFromOptions()
710: @*/
711: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
712: {
717: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
718: return(0);
719: }
721: /*@C
722: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
723: Mat options in the database.
725: Logically Collective on Mat
727: Input Parameters:
728: + A - the Mat context
729: - prefix - the prefix to prepend to all option names
731: Notes:
732: A hyphen (-) must NOT be given at the beginning of the prefix name.
733: The first character of all runtime options is AUTOMATICALLY the hyphen.
735: Level: advanced
737: .keywords: Mat, append, options, prefix, database
739: .seealso: MatGetOptionsPrefix()
740: @*/
741: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
742: {
747: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
748: return(0);
749: }
751: /*@C
752: MatGetOptionsPrefix - Sets the prefix used for searching for all
753: Mat options in the database.
755: Not Collective
757: Input Parameter:
758: . A - the Mat context
760: Output Parameter:
761: . prefix - pointer to the prefix string used
763: Notes: On the fortran side, the user should pass in a string 'prefix' of
764: sufficient length to hold the prefix.
766: Level: advanced
768: .keywords: Mat, get, options, prefix, database
770: .seealso: MatAppendOptionsPrefix()
771: @*/
772: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
773: {
778: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
779: return(0);
780: }
782: /*@
783: MatSetUp - Sets up the internal matrix data structures for the later use.
785: Collective on Mat
787: Input Parameters:
788: . A - the Mat context
790: Notes:
791: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
793: If a suitable preallocation routine is used, this function does not need to be called.
795: See the Performance chapter of the PETSc users manual for how to preallocate matrices
797: Level: beginner
799: .keywords: Mat, setup
801: .seealso: MatCreate(), MatDestroy()
802: @*/
803: PetscErrorCode MatSetUp(Mat A)
804: {
805: PetscMPIInt size;
810: if (!((PetscObject)A)->type_name) {
811: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
812: if (size == 1) {
813: MatSetType(A, MATSEQAIJ);
814: } else {
815: MatSetType(A, MATMPIAIJ);
816: }
817: }
818: if (!A->preallocated && A->ops->setup) {
819: PetscInfo(A,"Warning not preallocating matrix storage\n");
820: (*A->ops->setup)(A);
821: }
822: if (A->rmap->n < 0 || A->rmap->N < 0) {
823: PetscLayoutSetUp(A->rmap);
824: }
825: if (A->cmap->n < 0 || A->cmap->N < 0) {
826: PetscLayoutSetUp(A->cmap);
827: }
828: A->preallocated = PETSC_TRUE;
829: return(0);
830: }
832: #if defined(PETSC_HAVE_SAWS)
833: #include <petscviewersaws.h>
834: #endif
835: /*@C
836: MatView - Visualizes a matrix object.
838: Collective on Mat
840: Input Parameters:
841: + mat - the matrix
842: - viewer - visualization context
844: Notes:
845: The available visualization contexts include
846: + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
847: . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
848: . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
849: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
851: The user can open alternative visualization contexts with
852: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
853: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
854: specified file; corresponding input uses MatLoad()
855: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
856: an X window display
857: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
858: Currently only the sequential dense and AIJ
859: matrix types support the Socket viewer.
861: The user can call PetscViewerPushFormat() to specify the output
862: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
863: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
864: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
865: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
866: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
867: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
868: format common among all matrix types
869: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
870: format (which is in many cases the same as the default)
871: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
872: size and structure (not the matrix entries)
873: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
874: the matrix structure
876: Options Database Keys:
877: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatAssemblyEnd()
878: . -mat_view ::ascii_info_detail - Prints more detailed info
879: . -mat_view - Prints matrix in ASCII format
880: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
881: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
882: . -display <name> - Sets display name (default is host)
883: . -draw_pause <sec> - Sets number of seconds to pause after display
884: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 12 Using MATLAB with PETSc for details)
885: . -viewer_socket_machine <machine> -
886: . -viewer_socket_port <port> -
887: . -mat_view binary - save matrix to file in binary format
888: - -viewer_binary_filename <name> -
889: Level: beginner
891: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
892: viewer is used.
894: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
895: viewer is used.
897: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
898: And then use the following mouse functions:
899: left mouse: zoom in
900: middle mouse: zoom out
901: right mouse: continue with the simulation
903: Concepts: matrices^viewing
904: Concepts: matrices^plotting
905: Concepts: matrices^printing
907: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
908: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
909: @*/
910: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
911: {
912: PetscErrorCode ierr;
913: PetscInt rows,cols,rbs,cbs;
914: PetscBool iascii,ibinary;
915: PetscViewerFormat format;
916: #if defined(PETSC_HAVE_SAWS)
917: PetscBool issaws;
918: #endif
923: if (!viewer) {
924: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
925: }
928: MatCheckPreallocated(mat,1);
929: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
930: if (ibinary) {
931: PetscBool mpiio;
932: PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
933: if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
934: }
936: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
937: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
938: PetscViewerGetFormat(viewer,&format);
939: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
940: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
941: }
943: #if defined(PETSC_HAVE_SAWS)
944: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
945: #endif
946: if (iascii) {
947: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
948: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
949: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
950: PetscViewerASCIIPushTab(viewer);
951: MatGetSize(mat,&rows,&cols);
952: MatGetBlockSizes(mat,&rbs,&cbs);
953: if (rbs != 1 || cbs != 1) {
954: if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
955: else {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
956: } else {
957: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
958: }
959: if (mat->factortype) {
960: const MatSolverPackage solver;
961: MatFactorGetSolverPackage(mat,&solver);
962: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
963: }
964: if (mat->ops->getinfo) {
965: MatInfo info;
966: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
967: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
968: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
969: }
970: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
971: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
972: }
973: #if defined(PETSC_HAVE_SAWS)
974: } else if (issaws) {
975: PetscMPIInt rank;
977: PetscObjectName((PetscObject)mat);
978: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
979: if (!((PetscObject)mat)->amsmem && !rank) {
980: PetscObjectViewSAWs((PetscObject)mat,viewer);
981: }
982: #endif
983: }
984: if (mat->ops->view) {
985: PetscViewerASCIIPushTab(viewer);
986: (*mat->ops->view)(mat,viewer);
987: PetscViewerASCIIPopTab(viewer);
988: }
989: if (iascii) {
990: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
991: PetscViewerGetFormat(viewer,&format);
992: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
993: PetscViewerASCIIPopTab(viewer);
994: }
995: }
996: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
997: return(0);
998: }
1000: #if defined(PETSC_USE_DEBUG)
1001: #include <../src/sys/totalview/tv_data_display.h>
1002: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
1003: {
1004: TV_add_row("Local rows", "int", &mat->rmap->n);
1005: TV_add_row("Local columns", "int", &mat->cmap->n);
1006: TV_add_row("Global rows", "int", &mat->rmap->N);
1007: TV_add_row("Global columns", "int", &mat->cmap->N);
1008: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
1009: return TV_format_OK;
1010: }
1011: #endif
1013: /*@C
1014: MatLoad - Loads a matrix that has been stored in binary format
1015: with MatView(). The matrix format is determined from the options database.
1016: Generates a parallel MPI matrix if the communicator has more than one
1017: processor. The default matrix type is AIJ.
1019: Collective on PetscViewer
1021: Input Parameters:
1022: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
1023: or some related function before a call to MatLoad()
1024: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
1026: Options Database Keys:
1027: Used with block matrix formats (MATSEQBAIJ, ...) to specify
1028: block size
1029: . -matload_block_size <bs>
1031: Level: beginner
1033: Notes:
1034: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
1035: Mat before calling this routine if you wish to set it from the options database.
1037: MatLoad() automatically loads into the options database any options
1038: given in the file filename.info where filename is the name of the file
1039: that was passed to the PetscViewerBinaryOpen(). The options in the info
1040: file will be ignored if you use the -viewer_binary_skip_info option.
1042: If the type or size of newmat is not set before a call to MatLoad, PETSc
1043: sets the default matrix type AIJ and sets the local and global sizes.
1044: If type and/or size is already set, then the same are used.
1046: In parallel, each processor can load a subset of rows (or the
1047: entire matrix). This routine is especially useful when a large
1048: matrix is stored on disk and only part of it is desired on each
1049: processor. For example, a parallel solver may access only some of
1050: the rows from each processor. The algorithm used here reads
1051: relatively small blocks of data rather than reading the entire
1052: matrix and then subsetting it.
1054: Notes for advanced users:
1055: Most users should not need to know the details of the binary storage
1056: format, since MatLoad() and MatView() completely hide these details.
1057: But for anyone who's interested, the standard binary matrix storage
1058: format is
1060: $ int MAT_FILE_CLASSID
1061: $ int number of rows
1062: $ int number of columns
1063: $ int total number of nonzeros
1064: $ int *number nonzeros in each row
1065: $ int *column indices of all nonzeros (starting index is zero)
1066: $ PetscScalar *values of all nonzeros
1068: PETSc automatically does the byte swapping for
1069: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
1070: linux, Windows and the paragon; thus if you write your own binary
1071: read/write routines you have to swap the bytes; see PetscBinaryRead()
1072: and PetscBinaryWrite() to see how this may be done.
1074: .keywords: matrix, load, binary, input
1076: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
1078: @*/
1079: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
1080: {
1082: PetscBool isbinary,flg;
1087: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1088: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1090: if (!((PetscObject)newmat)->type_name) {
1091: MatSetType(newmat,MATAIJ);
1092: }
1094: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1095: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1096: (*newmat->ops->load)(newmat,viewer);
1097: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1099: flg = PETSC_FALSE;
1100: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1101: if (flg) {
1102: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1103: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1104: }
1105: flg = PETSC_FALSE;
1106: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1107: if (flg) {
1108: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1109: }
1110: return(0);
1111: }
1113: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1114: {
1116: Mat_Redundant *redund = *redundant;
1117: PetscInt i;
1120: if (redund){
1121: if (redund->matseq) { /* via MatCreateSubMatrices() */
1122: ISDestroy(&redund->isrow);
1123: ISDestroy(&redund->iscol);
1124: MatDestroySubMatrices(1,&redund->matseq);
1125: } else {
1126: PetscFree2(redund->send_rank,redund->recv_rank);
1127: PetscFree(redund->sbuf_j);
1128: PetscFree(redund->sbuf_a);
1129: for (i=0; i<redund->nrecvs; i++) {
1130: PetscFree(redund->rbuf_j[i]);
1131: PetscFree(redund->rbuf_a[i]);
1132: }
1133: PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1134: }
1136: if (redund->subcomm) {
1137: PetscCommDestroy(&redund->subcomm);
1138: }
1139: PetscFree(redund);
1140: }
1141: return(0);
1142: }
1144: /*@
1145: MatDestroy - Frees space taken by a matrix.
1147: Collective on Mat
1149: Input Parameter:
1150: . A - the matrix
1152: Level: beginner
1154: @*/
1155: PetscErrorCode MatDestroy(Mat *A)
1156: {
1160: if (!*A) return(0);
1162: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1164: /* if memory was published with SAWs then destroy it */
1165: PetscObjectSAWsViewOff((PetscObject)*A);
1166: if ((*A)->ops->destroy) {
1167: (*(*A)->ops->destroy)(*A);
1168: }
1170: PetscFree((*A)->solvertype);
1171: MatDestroy_Redundant(&(*A)->redundant);
1172: MatNullSpaceDestroy(&(*A)->nullsp);
1173: MatNullSpaceDestroy(&(*A)->transnullsp);
1174: MatNullSpaceDestroy(&(*A)->nearnullsp);
1175: MatDestroy(&(*A)->schur);
1176: PetscLayoutDestroy(&(*A)->rmap);
1177: PetscLayoutDestroy(&(*A)->cmap);
1178: PetscHeaderDestroy(A);
1179: return(0);
1180: }
1182: /*@C
1183: MatSetValues - Inserts or adds a block of values into a matrix.
1184: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1185: MUST be called after all calls to MatSetValues() have been completed.
1187: Not Collective
1189: Input Parameters:
1190: + mat - the matrix
1191: . v - a logically two-dimensional array of values
1192: . m, idxm - the number of rows and their global indices
1193: . n, idxn - the number of columns and their global indices
1194: - addv - either ADD_VALUES or INSERT_VALUES, where
1195: ADD_VALUES adds values to any existing entries, and
1196: INSERT_VALUES replaces existing entries with new values
1198: Notes:
1199: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1200: MatSetUp() before using this routine
1202: By default the values, v, are row-oriented. See MatSetOption() for other options.
1204: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1205: options cannot be mixed without intervening calls to the assembly
1206: routines.
1208: MatSetValues() uses 0-based row and column numbers in Fortran
1209: as well as in C.
1211: Negative indices may be passed in idxm and idxn, these rows and columns are
1212: simply ignored. This allows easily inserting element stiffness matrices
1213: with homogeneous Dirchlet boundary conditions that you don't want represented
1214: in the matrix.
1216: Efficiency Alert:
1217: The routine MatSetValuesBlocked() may offer much better efficiency
1218: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1220: Level: beginner
1222: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
1223: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
1225: Concepts: matrices^putting entries in
1227: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1228: InsertMode, INSERT_VALUES, ADD_VALUES
1229: @*/
1230: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1231: {
1233: #if defined(PETSC_USE_DEBUG)
1234: PetscInt i,j;
1235: #endif
1240: if (!m || !n) return(0); /* no values to insert */
1244: MatCheckPreallocated(mat,1);
1245: if (mat->insertmode == NOT_SET_VALUES) {
1246: mat->insertmode = addv;
1247: }
1248: #if defined(PETSC_USE_DEBUG)
1249: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1250: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1251: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1253: for (i=0; i<m; i++) {
1254: for (j=0; j<n; j++) {
1255: if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1256: #if defined(PETSC_USE_COMPLEX)
1257: SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g+ig at matrix entry (%D,%D)",(double)PetscRealPart(v[i*n+j]),(double)PetscImaginaryPart(v[i*n+j]),idxm[i],idxn[j]);
1258: #else
1259: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1260: #endif
1261: }
1262: }
1263: #endif
1265: if (mat->assembled) {
1266: mat->was_assembled = PETSC_TRUE;
1267: mat->assembled = PETSC_FALSE;
1268: }
1269: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1270: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1271: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1272: #if defined(PETSC_HAVE_CUSP)
1273: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1274: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1275: }
1276: #elif defined(PETSC_HAVE_VIENNACL)
1277: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1278: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1279: }
1280: #elif defined(PETSC_HAVE_VECCUDA)
1281: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1282: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1283: }
1284: #endif
1285: return(0);
1286: }
1289: /*@
1290: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1291: values into a matrix
1293: Not Collective
1295: Input Parameters:
1296: + mat - the matrix
1297: . row - the (block) row to set
1298: - v - a logically two-dimensional array of values
1300: Notes:
1301: By the values, v, are column-oriented (for the block version) and sorted
1303: All the nonzeros in the row must be provided
1305: The matrix must have previously had its column indices set
1307: The row must belong to this process
1309: Level: intermediate
1311: Concepts: matrices^putting entries in
1313: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1314: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1315: @*/
1316: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1317: {
1319: PetscInt globalrow;
1325: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1326: MatSetValuesRow(mat,globalrow,v);
1327: #if defined(PETSC_HAVE_CUSP)
1328: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1329: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1330: }
1331: #elif defined(PETSC_HAVE_VIENNACL)
1332: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1333: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1334: }
1335: #elif defined(PETSC_HAVE_VECCUDA)
1336: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1337: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1338: }
1339: #endif
1340: return(0);
1341: }
1343: /*@
1344: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1345: values into a matrix
1347: Not Collective
1349: Input Parameters:
1350: + mat - the matrix
1351: . row - the (block) row to set
1352: - v - a logically two-dimensional (column major) array of values for block matrices with blocksize larger than one, otherwise a one dimensional array of values
1354: Notes:
1355: The values, v, are column-oriented for the block version.
1357: All the nonzeros in the row must be provided
1359: THE MATRIX MUST HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1361: The row must belong to this process
1363: Level: advanced
1365: Concepts: matrices^putting entries in
1367: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1368: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1369: @*/
1370: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1371: {
1377: MatCheckPreallocated(mat,1);
1379: #if defined(PETSC_USE_DEBUG)
1380: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1381: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1382: #endif
1383: mat->insertmode = INSERT_VALUES;
1385: if (mat->assembled) {
1386: mat->was_assembled = PETSC_TRUE;
1387: mat->assembled = PETSC_FALSE;
1388: }
1389: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1390: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1391: (*mat->ops->setvaluesrow)(mat,row,v);
1392: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1393: #if defined(PETSC_HAVE_CUSP)
1394: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1395: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1396: }
1397: #elif defined(PETSC_HAVE_VIENNACL)
1398: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1399: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1400: }
1401: #elif defined(PETSC_HAVE_VECCUDA)
1402: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1403: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1404: }
1405: #endif
1406: return(0);
1407: }
1409: /*@
1410: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1411: Using structured grid indexing
1413: Not Collective
1415: Input Parameters:
1416: + mat - the matrix
1417: . m - number of rows being entered
1418: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1419: . n - number of columns being entered
1420: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1421: . v - a logically two-dimensional array of values
1422: - addv - either ADD_VALUES or INSERT_VALUES, where
1423: ADD_VALUES adds values to any existing entries, and
1424: INSERT_VALUES replaces existing entries with new values
1426: Notes:
1427: By default the values, v, are row-oriented. See MatSetOption() for other options.
1429: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1430: options cannot be mixed without intervening calls to the assembly
1431: routines.
1433: The grid coordinates are across the entire grid, not just the local portion
1435: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1436: as well as in C.
1438: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1440: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1441: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1443: The columns and rows in the stencil passed in MUST be contained within the
1444: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1445: if you create a DMDA with an overlap of one grid level and on a particular process its first
1446: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1447: first i index you can use in your column and row indices in MatSetStencil() is 5.
1449: In Fortran idxm and idxn should be declared as
1450: $ MatStencil idxm(4,m),idxn(4,n)
1451: and the values inserted using
1452: $ idxm(MatStencil_i,1) = i
1453: $ idxm(MatStencil_j,1) = j
1454: $ idxm(MatStencil_k,1) = k
1455: $ idxm(MatStencil_c,1) = c
1456: etc
1458: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1459: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1460: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1461: DM_BOUNDARY_PERIODIC boundary type.
1463: 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
1464: a single value per point) you can skip filling those indices.
1466: Inspired by the structured grid interface to the HYPRE package
1467: (http://www.llnl.gov/CASC/hypre)
1469: Efficiency Alert:
1470: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1471: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1473: Level: beginner
1475: Concepts: matrices^putting entries in
1477: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1478: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1479: @*/
1480: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1481: {
1483: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1484: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1485: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1488: if (!m || !n) return(0); /* no values to insert */
1495: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1496: jdxm = buf; jdxn = buf+m;
1497: } else {
1498: PetscMalloc2(m,&bufm,n,&bufn);
1499: jdxm = bufm; jdxn = bufn;
1500: }
1501: for (i=0; i<m; i++) {
1502: for (j=0; j<3-sdim; j++) dxm++;
1503: tmp = *dxm++ - starts[0];
1504: for (j=0; j<dim-1; j++) {
1505: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1506: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1507: }
1508: if (mat->stencil.noc) dxm++;
1509: jdxm[i] = tmp;
1510: }
1511: for (i=0; i<n; i++) {
1512: for (j=0; j<3-sdim; j++) dxn++;
1513: tmp = *dxn++ - starts[0];
1514: for (j=0; j<dim-1; j++) {
1515: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1516: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1517: }
1518: if (mat->stencil.noc) dxn++;
1519: jdxn[i] = tmp;
1520: }
1521: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1522: PetscFree2(bufm,bufn);
1523: return(0);
1524: }
1526: /*@
1527: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1528: Using structured grid indexing
1530: Not Collective
1532: Input Parameters:
1533: + mat - the matrix
1534: . m - number of rows being entered
1535: . idxm - grid coordinates for matrix rows being entered
1536: . n - number of columns being entered
1537: . idxn - grid coordinates for matrix columns being entered
1538: . v - a logically two-dimensional array of values
1539: - addv - either ADD_VALUES or INSERT_VALUES, where
1540: ADD_VALUES adds values to any existing entries, and
1541: INSERT_VALUES replaces existing entries with new values
1543: Notes:
1544: By default the values, v, are row-oriented and unsorted.
1545: See MatSetOption() for other options.
1547: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1548: options cannot be mixed without intervening calls to the assembly
1549: routines.
1551: The grid coordinates are across the entire grid, not just the local portion
1553: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1554: as well as in C.
1556: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1558: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1559: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1561: The columns and rows in the stencil passed in MUST be contained within the
1562: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1563: if you create a DMDA with an overlap of one grid level and on a particular process its first
1564: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1565: first i index you can use in your column and row indices in MatSetStencil() is 5.
1567: In Fortran idxm and idxn should be declared as
1568: $ MatStencil idxm(4,m),idxn(4,n)
1569: and the values inserted using
1570: $ idxm(MatStencil_i,1) = i
1571: $ idxm(MatStencil_j,1) = j
1572: $ idxm(MatStencil_k,1) = k
1573: etc
1575: Negative indices may be passed in idxm and idxn, these rows and columns are
1576: simply ignored. This allows easily inserting element stiffness matrices
1577: with homogeneous Dirchlet boundary conditions that you don't want represented
1578: in the matrix.
1580: Inspired by the structured grid interface to the HYPRE package
1581: (http://www.llnl.gov/CASC/hypre)
1583: Level: beginner
1585: Concepts: matrices^putting entries in
1587: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1588: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1589: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1590: @*/
1591: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1592: {
1594: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1595: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1596: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1599: if (!m || !n) return(0); /* no values to insert */
1606: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1607: jdxm = buf; jdxn = buf+m;
1608: } else {
1609: PetscMalloc2(m,&bufm,n,&bufn);
1610: jdxm = bufm; jdxn = bufn;
1611: }
1612: for (i=0; i<m; i++) {
1613: for (j=0; j<3-sdim; j++) dxm++;
1614: tmp = *dxm++ - starts[0];
1615: for (j=0; j<sdim-1; j++) {
1616: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1617: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1618: }
1619: dxm++;
1620: jdxm[i] = tmp;
1621: }
1622: for (i=0; i<n; i++) {
1623: for (j=0; j<3-sdim; j++) dxn++;
1624: tmp = *dxn++ - starts[0];
1625: for (j=0; j<sdim-1; j++) {
1626: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1627: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1628: }
1629: dxn++;
1630: jdxn[i] = tmp;
1631: }
1632: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1633: PetscFree2(bufm,bufn);
1634: #if defined(PETSC_HAVE_CUSP)
1635: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1636: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1637: }
1638: #elif defined(PETSC_HAVE_VIENNACL)
1639: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1640: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1641: }
1642: #elif defined(PETSC_HAVE_VECCUDA)
1643: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1644: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1645: }
1646: #endif
1647: return(0);
1648: }
1650: /*@
1651: MatSetStencil - Sets the grid information for setting values into a matrix via
1652: MatSetValuesStencil()
1654: Not Collective
1656: Input Parameters:
1657: + mat - the matrix
1658: . dim - dimension of the grid 1, 2, or 3
1659: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1660: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1661: - dof - number of degrees of freedom per node
1664: Inspired by the structured grid interface to the HYPRE package
1665: (www.llnl.gov/CASC/hyper)
1667: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1668: user.
1670: Level: beginner
1672: Concepts: matrices^putting entries in
1674: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1675: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1676: @*/
1677: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1678: {
1679: PetscInt i;
1686: mat->stencil.dim = dim + (dof > 1);
1687: for (i=0; i<dim; i++) {
1688: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1689: mat->stencil.starts[i] = starts[dim-i-1];
1690: }
1691: mat->stencil.dims[dim] = dof;
1692: mat->stencil.starts[dim] = 0;
1693: mat->stencil.noc = (PetscBool)(dof == 1);
1694: return(0);
1695: }
1697: /*@C
1698: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1700: Not Collective
1702: Input Parameters:
1703: + mat - the matrix
1704: . v - a logically two-dimensional array of values
1705: . m, idxm - the number of block rows and their global block indices
1706: . n, idxn - the number of block columns and their global block indices
1707: - addv - either ADD_VALUES or INSERT_VALUES, where
1708: ADD_VALUES adds values to any existing entries, and
1709: INSERT_VALUES replaces existing entries with new values
1711: Notes:
1712: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1713: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1715: The m and n count the NUMBER of blocks in the row direction and column direction,
1716: NOT the total number of rows/columns; for example, if the block size is 2 and
1717: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1718: The values in idxm would be 1 2; that is the first index for each block divided by
1719: the block size.
1721: Note that you must call MatSetBlockSize() when constructing this matrix (before
1722: preallocating it).
1724: By default the values, v, are row-oriented, so the layout of
1725: v is the same as for MatSetValues(). See MatSetOption() for other options.
1727: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1728: options cannot be mixed without intervening calls to the assembly
1729: routines.
1731: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1732: as well as in C.
1734: Negative indices may be passed in idxm and idxn, these rows and columns are
1735: simply ignored. This allows easily inserting element stiffness matrices
1736: with homogeneous Dirchlet boundary conditions that you don't want represented
1737: in the matrix.
1739: Each time an entry is set within a sparse matrix via MatSetValues(),
1740: internal searching must be done to determine where to place the
1741: data in the matrix storage space. By instead inserting blocks of
1742: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1743: reduced.
1745: Example:
1746: $ Suppose m=n=2 and block size(bs) = 2 The array is
1747: $
1748: $ 1 2 | 3 4
1749: $ 5 6 | 7 8
1750: $ - - - | - - -
1751: $ 9 10 | 11 12
1752: $ 13 14 | 15 16
1753: $
1754: $ v[] should be passed in like
1755: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1756: $
1757: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1758: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1760: Level: intermediate
1762: Concepts: matrices^putting entries in blocked
1764: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1765: @*/
1766: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1767: {
1773: if (!m || !n) return(0); /* no values to insert */
1777: MatCheckPreallocated(mat,1);
1778: if (mat->insertmode == NOT_SET_VALUES) {
1779: mat->insertmode = addv;
1780: }
1781: #if defined(PETSC_USE_DEBUG)
1782: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1783: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1784: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1785: #endif
1787: if (mat->assembled) {
1788: mat->was_assembled = PETSC_TRUE;
1789: mat->assembled = PETSC_FALSE;
1790: }
1791: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1792: if (mat->ops->setvaluesblocked) {
1793: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1794: } else {
1795: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1796: PetscInt i,j,bs,cbs;
1797: MatGetBlockSizes(mat,&bs,&cbs);
1798: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1799: iidxm = buf; iidxn = buf + m*bs;
1800: } else {
1801: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1802: iidxm = bufr; iidxn = bufc;
1803: }
1804: for (i=0; i<m; i++) {
1805: for (j=0; j<bs; j++) {
1806: iidxm[i*bs+j] = bs*idxm[i] + j;
1807: }
1808: }
1809: for (i=0; i<n; i++) {
1810: for (j=0; j<cbs; j++) {
1811: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1812: }
1813: }
1814: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1815: PetscFree2(bufr,bufc);
1816: }
1817: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1818: #if defined(PETSC_HAVE_CUSP)
1819: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1820: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1821: }
1822: #elif defined(PETSC_HAVE_VIENNACL)
1823: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1824: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1825: }
1826: #elif defined(PETSC_HAVE_VECCUDA)
1827: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1828: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1829: }
1830: #endif
1831: return(0);
1832: }
1834: /*@
1835: MatGetValues - Gets a block of values from a matrix.
1837: Not Collective; currently only returns a local block
1839: Input Parameters:
1840: + mat - the matrix
1841: . v - a logically two-dimensional array for storing the values
1842: . m, idxm - the number of rows and their global indices
1843: - n, idxn - the number of columns and their global indices
1845: Notes:
1846: The user must allocate space (m*n PetscScalars) for the values, v.
1847: The values, v, are then returned in a row-oriented format,
1848: analogous to that used by default in MatSetValues().
1850: MatGetValues() uses 0-based row and column numbers in
1851: Fortran as well as in C.
1853: MatGetValues() requires that the matrix has been assembled
1854: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1855: MatSetValues() and MatGetValues() CANNOT be made in succession
1856: without intermediate matrix assembly.
1858: Negative row or column indices will be ignored and those locations in v[] will be
1859: left unchanged.
1861: Level: advanced
1863: Concepts: matrices^accessing values
1865: .seealso: MatGetRow(), MatCreateSubMatrices(), MatSetValues()
1866: @*/
1867: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1868: {
1874: if (!m || !n) return(0);
1878: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1879: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1880: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1881: MatCheckPreallocated(mat,1);
1883: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1884: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1885: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1886: return(0);
1887: }
1889: /*@
1890: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1891: the same size. Currently, this can only be called once and creates the given matrix.
1893: Not Collective
1895: Input Parameters:
1896: + mat - the matrix
1897: . nb - the number of blocks
1898: . bs - the number of rows (and columns) in each block
1899: . rows - a concatenation of the rows for each block
1900: - v - a concatenation of logically two-dimensional arrays of values
1902: Notes:
1903: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1905: Level: advanced
1907: Concepts: matrices^putting entries in
1909: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1910: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1911: @*/
1912: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1913: {
1921: #if defined(PETSC_USE_DEBUG)
1922: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1923: #endif
1925: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1926: if (mat->ops->setvaluesbatch) {
1927: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1928: } else {
1929: PetscInt b;
1930: for (b = 0; b < nb; ++b) {
1931: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1932: }
1933: }
1934: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1935: return(0);
1936: }
1938: /*@
1939: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1940: the routine MatSetValuesLocal() to allow users to insert matrix entries
1941: using a local (per-processor) numbering.
1943: Not Collective
1945: Input Parameters:
1946: + x - the matrix
1947: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1948: - cmapping - column mapping
1950: Level: intermediate
1952: Concepts: matrices^local to global mapping
1953: Concepts: local to global mapping^for matrices
1955: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1956: @*/
1957: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1958: {
1967: if (x->ops->setlocaltoglobalmapping) {
1968: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1969: } else {
1970: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1971: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1972: }
1973: return(0);
1974: }
1977: /*@
1978: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1980: Not Collective
1982: Input Parameters:
1983: . A - the matrix
1985: Output Parameters:
1986: + rmapping - row mapping
1987: - cmapping - column mapping
1989: Level: advanced
1991: Concepts: matrices^local to global mapping
1992: Concepts: local to global mapping^for matrices
1994: .seealso: MatSetValuesLocal()
1995: @*/
1996: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1997: {
2003: if (rmapping) *rmapping = A->rmap->mapping;
2004: if (cmapping) *cmapping = A->cmap->mapping;
2005: return(0);
2006: }
2008: /*@
2009: MatGetLayouts - Gets the PetscLayout objects for rows and columns
2011: Not Collective
2013: Input Parameters:
2014: . A - the matrix
2016: Output Parameters:
2017: + rmap - row layout
2018: - cmap - column layout
2020: Level: advanced
2022: .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping()
2023: @*/
2024: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
2025: {
2031: if (rmap) *rmap = A->rmap;
2032: if (cmap) *cmap = A->cmap;
2033: return(0);
2034: }
2036: /*@C
2037: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
2038: using a local ordering of the nodes.
2040: Not Collective
2042: Input Parameters:
2043: + mat - the matrix
2044: . nrow, irow - number of rows and their local indices
2045: . ncol, icol - number of columns and their local indices
2046: . y - a logically two-dimensional array of values
2047: - addv - either INSERT_VALUES or ADD_VALUES, where
2048: ADD_VALUES adds values to any existing entries, and
2049: INSERT_VALUES replaces existing entries with new values
2051: Notes:
2052: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2053: MatSetUp() before using this routine
2055: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2057: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2058: options cannot be mixed without intervening calls to the assembly
2059: routines.
2061: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2062: MUST be called after all calls to MatSetValuesLocal() have been completed.
2064: Level: intermediate
2066: Concepts: matrices^putting entries in with local numbering
2068: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2069: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2071: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2072: MatSetValueLocal()
2073: @*/
2074: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2075: {
2081: MatCheckPreallocated(mat,1);
2082: if (!nrow || !ncol) return(0); /* no values to insert */
2086: if (mat->insertmode == NOT_SET_VALUES) {
2087: mat->insertmode = addv;
2088: }
2089: #if defined(PETSC_USE_DEBUG)
2090: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2091: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2092: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2093: #endif
2095: if (mat->assembled) {
2096: mat->was_assembled = PETSC_TRUE;
2097: mat->assembled = PETSC_FALSE;
2098: }
2099: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2100: if (mat->ops->setvalueslocal) {
2101: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2102: } else {
2103: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2104: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2105: irowm = buf; icolm = buf+nrow;
2106: } else {
2107: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2108: irowm = bufr; icolm = bufc;
2109: }
2110: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2111: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2112: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2113: PetscFree2(bufr,bufc);
2114: }
2115: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2116: #if defined(PETSC_HAVE_CUSP)
2117: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2118: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2119: }
2120: #elif defined(PETSC_HAVE_VIENNACL)
2121: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2122: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2123: }
2124: #elif defined(PETSC_HAVE_VECCUDA)
2125: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2126: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2127: }
2128: #endif
2129: return(0);
2130: }
2132: /*@C
2133: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2134: using a local ordering of the nodes a block at a time.
2136: Not Collective
2138: Input Parameters:
2139: + x - the matrix
2140: . nrow, irow - number of rows and their local indices
2141: . ncol, icol - number of columns and their local indices
2142: . y - a logically two-dimensional array of values
2143: - addv - either INSERT_VALUES or ADD_VALUES, where
2144: ADD_VALUES adds values to any existing entries, and
2145: INSERT_VALUES replaces existing entries with new values
2147: Notes:
2148: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2149: MatSetUp() before using this routine
2151: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2152: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2154: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2155: options cannot be mixed without intervening calls to the assembly
2156: routines.
2158: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2159: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2161: Level: intermediate
2163: Developer Notes: This is labeled with C so does not automatically generate Fortran stubs and interfaces
2164: because it requires multiple Fortran interfaces depending on which arguments are scalar or arrays.
2166: Concepts: matrices^putting blocked values in with local numbering
2168: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2169: MatSetValuesLocal(), MatSetValuesBlocked()
2170: @*/
2171: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2172: {
2178: MatCheckPreallocated(mat,1);
2179: if (!nrow || !ncol) return(0); /* no values to insert */
2183: if (mat->insertmode == NOT_SET_VALUES) {
2184: mat->insertmode = addv;
2185: }
2186: #if defined(PETSC_USE_DEBUG)
2187: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2188: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2189: 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);
2190: #endif
2192: if (mat->assembled) {
2193: mat->was_assembled = PETSC_TRUE;
2194: mat->assembled = PETSC_FALSE;
2195: }
2196: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2197: if (mat->ops->setvaluesblockedlocal) {
2198: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2199: } else {
2200: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2201: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2202: irowm = buf; icolm = buf + nrow;
2203: } else {
2204: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2205: irowm = bufr; icolm = bufc;
2206: }
2207: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2208: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2209: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2210: PetscFree2(bufr,bufc);
2211: }
2212: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2213: #if defined(PETSC_HAVE_CUSP)
2214: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2215: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2216: }
2217: #elif defined(PETSC_HAVE_VIENNACL)
2218: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2219: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2220: }
2221: #elif defined(PETSC_HAVE_VECCUDA)
2222: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2223: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2224: }
2225: #endif
2226: return(0);
2227: }
2229: /*@
2230: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2232: Collective on Mat and Vec
2234: Input Parameters:
2235: + mat - the matrix
2236: - x - the vector to be multiplied
2238: Output Parameters:
2239: . y - the result
2241: Notes:
2242: The vectors x and y cannot be the same. I.e., one cannot
2243: call MatMult(A,y,y).
2245: Level: developer
2247: Concepts: matrix-vector product
2249: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2250: @*/
2251: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2252: {
2261: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2262: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2263: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2264: MatCheckPreallocated(mat,1);
2266: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2267: (*mat->ops->multdiagonalblock)(mat,x,y);
2268: PetscObjectStateIncrease((PetscObject)y);
2269: return(0);
2270: }
2272: /* --------------------------------------------------------*/
2273: /*@
2274: MatMult - Computes the matrix-vector product, y = Ax.
2276: Neighbor-wise Collective on Mat and Vec
2278: Input Parameters:
2279: + mat - the matrix
2280: - x - the vector to be multiplied
2282: Output Parameters:
2283: . y - the result
2285: Notes:
2286: The vectors x and y cannot be the same. I.e., one cannot
2287: call MatMult(A,y,y).
2289: Level: beginner
2291: Concepts: matrix-vector product
2293: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2294: @*/
2295: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2296: {
2304: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2305: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2306: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2307: #if !defined(PETSC_HAVE_CONSTRAINTS)
2308: 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);
2309: 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);
2310: 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);
2311: #endif
2312: VecLocked(y,3);
2313: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2314: MatCheckPreallocated(mat,1);
2316: VecLockPush(x);
2317: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2318: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2319: (*mat->ops->mult)(mat,x,y);
2320: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2321: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2322: VecLockPop(x);
2323: return(0);
2324: }
2326: /*@
2327: MatMultTranspose - Computes matrix transpose times a vector.
2329: Neighbor-wise Collective on Mat and Vec
2331: Input Parameters:
2332: + mat - the matrix
2333: - x - the vector to be multilplied
2335: Output Parameters:
2336: . y - the result
2338: Notes:
2339: The vectors x and y cannot be the same. I.e., one cannot
2340: call MatMultTranspose(A,y,y).
2342: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2343: use MatMultHermitianTranspose()
2345: Level: beginner
2347: Concepts: matrix vector product^transpose
2349: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2350: @*/
2351: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2352: {
2361: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2362: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2363: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2364: #if !defined(PETSC_HAVE_CONSTRAINTS)
2365: 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);
2366: 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);
2367: #endif
2368: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2369: MatCheckPreallocated(mat,1);
2371: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2372: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2373: VecLockPush(x);
2374: (*mat->ops->multtranspose)(mat,x,y);
2375: VecLockPop(x);
2376: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2377: PetscObjectStateIncrease((PetscObject)y);
2378: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2379: return(0);
2380: }
2382: /*@
2383: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2385: Neighbor-wise Collective on Mat and Vec
2387: Input Parameters:
2388: + mat - the matrix
2389: - x - the vector to be multilplied
2391: Output Parameters:
2392: . y - the result
2394: Notes:
2395: The vectors x and y cannot be the same. I.e., one cannot
2396: call MatMultHermitianTranspose(A,y,y).
2398: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2400: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2402: Level: beginner
2404: Concepts: matrix vector product^transpose
2406: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2407: @*/
2408: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2409: {
2411: Vec w;
2419: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2420: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2421: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2422: #if !defined(PETSC_HAVE_CONSTRAINTS)
2423: 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);
2424: 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);
2425: #endif
2426: MatCheckPreallocated(mat,1);
2428: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2429: if (mat->ops->multhermitiantranspose) {
2430: VecLockPush(x);
2431: (*mat->ops->multhermitiantranspose)(mat,x,y);
2432: VecLockPop(x);
2433: } else {
2434: VecDuplicate(x,&w);
2435: VecCopy(x,w);
2436: VecConjugate(w);
2437: MatMultTranspose(mat,w,y);
2438: VecDestroy(&w);
2439: VecConjugate(y);
2440: }
2441: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2442: PetscObjectStateIncrease((PetscObject)y);
2443: return(0);
2444: }
2446: /*@
2447: MatMultAdd - Computes v3 = v2 + A * v1.
2449: Neighbor-wise Collective on Mat and Vec
2451: Input Parameters:
2452: + mat - the matrix
2453: - v1, v2 - the vectors
2455: Output Parameters:
2456: . v3 - the result
2458: Notes:
2459: The vectors v1 and v3 cannot be the same. I.e., one cannot
2460: call MatMultAdd(A,v1,v2,v1).
2462: Level: beginner
2464: Concepts: matrix vector product^addition
2466: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2467: @*/
2468: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2469: {
2479: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2480: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2481: 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);
2482: /* 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);
2483: 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); */
2484: 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);
2485: 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);
2486: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2487: MatCheckPreallocated(mat,1);
2489: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2490: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2491: VecLockPush(v1);
2492: (*mat->ops->multadd)(mat,v1,v2,v3);
2493: VecLockPop(v1);
2494: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2495: PetscObjectStateIncrease((PetscObject)v3);
2496: return(0);
2497: }
2499: /*@
2500: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2502: Neighbor-wise Collective on Mat and Vec
2504: Input Parameters:
2505: + mat - the matrix
2506: - v1, v2 - the vectors
2508: Output Parameters:
2509: . v3 - the result
2511: Notes:
2512: The vectors v1 and v3 cannot be the same. I.e., one cannot
2513: call MatMultTransposeAdd(A,v1,v2,v1).
2515: Level: beginner
2517: Concepts: matrix vector product^transpose and addition
2519: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2520: @*/
2521: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2522: {
2532: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2533: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2534: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2535: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2536: 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);
2537: 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);
2538: 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);
2539: MatCheckPreallocated(mat,1);
2541: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2542: VecLockPush(v1);
2543: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2544: VecLockPop(v1);
2545: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2546: PetscObjectStateIncrease((PetscObject)v3);
2547: return(0);
2548: }
2550: /*@
2551: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2553: Neighbor-wise Collective on Mat and Vec
2555: Input Parameters:
2556: + mat - the matrix
2557: - v1, v2 - the vectors
2559: Output Parameters:
2560: . v3 - the result
2562: Notes:
2563: The vectors v1 and v3 cannot be the same. I.e., one cannot
2564: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2566: Level: beginner
2568: Concepts: matrix vector product^transpose and addition
2570: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2571: @*/
2572: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2573: {
2583: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2584: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2585: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2586: 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);
2587: 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);
2588: 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);
2589: MatCheckPreallocated(mat,1);
2591: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2592: VecLockPush(v1);
2593: if (mat->ops->multhermitiantransposeadd) {
2594: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2595: } else {
2596: Vec w,z;
2597: VecDuplicate(v1,&w);
2598: VecCopy(v1,w);
2599: VecConjugate(w);
2600: VecDuplicate(v3,&z);
2601: MatMultTranspose(mat,w,z);
2602: VecDestroy(&w);
2603: VecConjugate(z);
2604: VecWAXPY(v3,1.0,v2,z);
2605: VecDestroy(&z);
2606: }
2607: VecLockPop(v1);
2608: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2609: PetscObjectStateIncrease((PetscObject)v3);
2610: return(0);
2611: }
2613: /*@
2614: MatMultConstrained - The inner multiplication routine for a
2615: constrained matrix P^T A P.
2617: Neighbor-wise Collective on Mat and Vec
2619: Input Parameters:
2620: + mat - the matrix
2621: - x - the vector to be multilplied
2623: Output Parameters:
2624: . y - the result
2626: Notes:
2627: The vectors x and y cannot be the same. I.e., one cannot
2628: call MatMult(A,y,y).
2630: Level: beginner
2632: .keywords: matrix, multiply, matrix-vector product, constraint
2633: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2634: @*/
2635: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2636: {
2643: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2644: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2645: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2646: 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);
2647: 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);
2648: 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);
2650: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2651: VecLockPush(x);
2652: (*mat->ops->multconstrained)(mat,x,y);
2653: VecLockPop(x);
2654: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2655: PetscObjectStateIncrease((PetscObject)y);
2656: return(0);
2657: }
2659: /*@
2660: MatMultTransposeConstrained - The inner multiplication routine for a
2661: constrained matrix P^T A^T P.
2663: Neighbor-wise Collective on Mat and Vec
2665: Input Parameters:
2666: + mat - the matrix
2667: - x - the vector to be multilplied
2669: Output Parameters:
2670: . y - the result
2672: Notes:
2673: The vectors x and y cannot be the same. I.e., one cannot
2674: call MatMult(A,y,y).
2676: Level: beginner
2678: .keywords: matrix, multiply, matrix-vector product, constraint
2679: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2680: @*/
2681: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2682: {
2689: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2690: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2691: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2692: 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);
2693: 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);
2695: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2696: (*mat->ops->multtransposeconstrained)(mat,x,y);
2697: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2698: PetscObjectStateIncrease((PetscObject)y);
2699: return(0);
2700: }
2702: /*@C
2703: MatGetFactorType - gets the type of factorization it is
2705: Note Collective
2706: as the flag
2708: Input Parameters:
2709: . mat - the matrix
2711: Output Parameters:
2712: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2714: Level: intermediate
2716: .seealso: MatFactorType, MatGetFactor()
2717: @*/
2718: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2719: {
2723: *t = mat->factortype;
2724: return(0);
2725: }
2727: /* ------------------------------------------------------------*/
2728: /*@C
2729: MatGetInfo - Returns information about matrix storage (number of
2730: nonzeros, memory, etc.).
2732: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2734: Input Parameters:
2735: . mat - the matrix
2737: Output Parameters:
2738: + flag - flag indicating the type of parameters to be returned
2739: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2740: MAT_GLOBAL_SUM - sum over all processors)
2741: - info - matrix information context
2743: Notes:
2744: The MatInfo context contains a variety of matrix data, including
2745: number of nonzeros allocated and used, number of mallocs during
2746: matrix assembly, etc. Additional information for factored matrices
2747: is provided (such as the fill ratio, number of mallocs during
2748: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2749: when using the runtime options
2750: $ -info -mat_view ::ascii_info
2752: Example for C/C++ Users:
2753: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2754: data within the MatInfo context. For example,
2755: .vb
2756: MatInfo info;
2757: Mat A;
2758: double mal, nz_a, nz_u;
2760: MatGetInfo(A,MAT_LOCAL,&info);
2761: mal = info.mallocs;
2762: nz_a = info.nz_allocated;
2763: .ve
2765: Example for Fortran Users:
2766: Fortran users should declare info as a double precision
2767: array of dimension MAT_INFO_SIZE, and then extract the parameters
2768: of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2769: a complete list of parameter names.
2770: .vb
2771: double precision info(MAT_INFO_SIZE)
2772: double precision mal, nz_a
2773: Mat A
2774: integer ierr
2776: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2777: mal = info(MAT_INFO_MALLOCS)
2778: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2779: .ve
2781: Level: intermediate
2783: Concepts: matrices^getting information on
2785: Developer Note: fortran interface is not autogenerated as the f90
2786: interface defintion cannot be generated correctly [due to MatInfo]
2788: .seealso: MatStashGetInfo()
2790: @*/
2791: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2792: {
2799: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2800: MatCheckPreallocated(mat,1);
2801: (*mat->ops->getinfo)(mat,flag,info);
2802: return(0);
2803: }
2805: /*
2806: This is used by external packages where it is not easy to get the info from the actual
2807: matrix factorization.
2808: */
2809: PetscErrorCode MatGetInfo_External(Mat A,MatInfoType flag,MatInfo *info)
2810: {
2814: PetscMemzero(info,sizeof(MatInfo));
2815: return(0);
2816: }
2818: /* ----------------------------------------------------------*/
2820: /*@C
2821: MatLUFactor - Performs in-place LU factorization of matrix.
2823: Collective on Mat
2825: Input Parameters:
2826: + mat - the matrix
2827: . row - row permutation
2828: . col - column permutation
2829: - info - options for factorization, includes
2830: $ fill - expected fill as ratio of original fill.
2831: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2832: $ Run with the option -info to determine an optimal value to use
2834: Notes:
2835: Most users should employ the simplified KSP interface for linear solvers
2836: instead of working directly with matrix algebra routines such as this.
2837: See, e.g., KSPCreate().
2839: This changes the state of the matrix to a factored matrix; it cannot be used
2840: for example with MatSetValues() unless one first calls MatSetUnfactored().
2842: Level: developer
2844: Concepts: matrices^LU factorization
2846: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2847: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2849: Developer Note: fortran interface is not autogenerated as the f90
2850: interface defintion cannot be generated correctly [due to MatFactorInfo]
2852: @*/
2853: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2854: {
2856: MatFactorInfo tinfo;
2864: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2865: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2866: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2867: MatCheckPreallocated(mat,1);
2868: if (!info) {
2869: MatFactorInfoInitialize(&tinfo);
2870: info = &tinfo;
2871: }
2873: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2874: (*mat->ops->lufactor)(mat,row,col,info);
2875: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2876: PetscObjectStateIncrease((PetscObject)mat);
2877: return(0);
2878: }
2880: /*@C
2881: MatILUFactor - Performs in-place ILU factorization of matrix.
2883: Collective on Mat
2885: Input Parameters:
2886: + mat - the matrix
2887: . row - row permutation
2888: . col - column permutation
2889: - info - structure containing
2890: $ levels - number of levels of fill.
2891: $ expected fill - as ratio of original fill.
2892: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2893: missing diagonal entries)
2895: Notes:
2896: Probably really in-place only when level of fill is zero, otherwise allocates
2897: new space to store factored matrix and deletes previous memory.
2899: Most users should employ the simplified KSP interface for linear solvers
2900: instead of working directly with matrix algebra routines such as this.
2901: See, e.g., KSPCreate().
2903: Level: developer
2905: Concepts: matrices^ILU factorization
2907: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2909: Developer Note: fortran interface is not autogenerated as the f90
2910: interface defintion cannot be generated correctly [due to MatFactorInfo]
2912: @*/
2913: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2914: {
2923: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2924: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2925: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2926: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2927: MatCheckPreallocated(mat,1);
2929: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2930: (*mat->ops->ilufactor)(mat,row,col,info);
2931: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2932: PetscObjectStateIncrease((PetscObject)mat);
2933: return(0);
2934: }
2936: /*@C
2937: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2938: Call this routine before calling MatLUFactorNumeric().
2940: Collective on Mat
2942: Input Parameters:
2943: + fact - the factor matrix obtained with MatGetFactor()
2944: . mat - the matrix
2945: . row, col - row and column permutations
2946: - info - options for factorization, includes
2947: $ fill - expected fill as ratio of original fill.
2948: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2949: $ Run with the option -info to determine an optimal value to use
2952: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2954: Most users should employ the simplified KSP interface for linear solvers
2955: instead of working directly with matrix algebra routines such as this.
2956: See, e.g., KSPCreate().
2958: Level: developer
2960: Concepts: matrices^LU symbolic factorization
2962: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2964: Developer Note: fortran interface is not autogenerated as the f90
2965: interface defintion cannot be generated correctly [due to MatFactorInfo]
2967: @*/
2968: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2969: {
2979: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2980: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2981: if (!(fact)->ops->lufactorsymbolic) {
2982: const MatSolverPackage spackage;
2983: MatFactorGetSolverPackage(fact,&spackage);
2984: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2985: }
2986: MatCheckPreallocated(mat,2);
2988: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2989: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2990: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2991: PetscObjectStateIncrease((PetscObject)fact);
2992: return(0);
2993: }
2995: /*@C
2996: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2997: Call this routine after first calling MatLUFactorSymbolic().
2999: Collective on Mat
3001: Input Parameters:
3002: + fact - the factor matrix obtained with MatGetFactor()
3003: . mat - the matrix
3004: - info - options for factorization
3006: Notes:
3007: See MatLUFactor() for in-place factorization. See
3008: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
3010: Most users should employ the simplified KSP interface for linear solvers
3011: instead of working directly with matrix algebra routines such as this.
3012: See, e.g., KSPCreate().
3014: Level: developer
3016: Concepts: matrices^LU numeric factorization
3018: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
3020: Developer Note: fortran interface is not autogenerated as the f90
3021: interface defintion cannot be generated correctly [due to MatFactorInfo]
3023: @*/
3024: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3025: {
3033: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3034: 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);
3036: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
3037: MatCheckPreallocated(mat,2);
3038: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
3039: (fact->ops->lufactornumeric)(fact,mat,info);
3040: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
3041: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3042: PetscObjectStateIncrease((PetscObject)fact);
3043: return(0);
3044: }
3046: /*@C
3047: MatCholeskyFactor - Performs in-place Cholesky factorization of a
3048: symmetric matrix.
3050: Collective on Mat
3052: Input Parameters:
3053: + mat - the matrix
3054: . perm - row and column permutations
3055: - f - expected fill as ratio of original fill
3057: Notes:
3058: See MatLUFactor() for the nonsymmetric case. See also
3059: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3061: Most users should employ the simplified KSP interface for linear solvers
3062: instead of working directly with matrix algebra routines such as this.
3063: See, e.g., KSPCreate().
3065: Level: developer
3067: Concepts: matrices^Cholesky factorization
3069: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3070: MatGetOrdering()
3072: Developer Note: fortran interface is not autogenerated as the f90
3073: interface defintion cannot be generated correctly [due to MatFactorInfo]
3075: @*/
3076: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3077: {
3085: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3086: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3087: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3088: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"In-place factorization for Mat type %s is not supported, try out-of-place factorization. See MatCholeskyFactorSymbolic/Numeric",((PetscObject)mat)->type_name);
3089: MatCheckPreallocated(mat,1);
3091: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3092: (*mat->ops->choleskyfactor)(mat,perm,info);
3093: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3094: PetscObjectStateIncrease((PetscObject)mat);
3095: return(0);
3096: }
3098: /*@C
3099: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3100: of a symmetric matrix.
3102: Collective on Mat
3104: Input Parameters:
3105: + fact - the factor matrix obtained with MatGetFactor()
3106: . mat - the matrix
3107: . perm - row and column permutations
3108: - info - options for factorization, includes
3109: $ fill - expected fill as ratio of original fill.
3110: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3111: $ Run with the option -info to determine an optimal value to use
3113: Notes:
3114: See MatLUFactorSymbolic() for the nonsymmetric case. See also
3115: MatCholeskyFactor() and MatCholeskyFactorNumeric().
3117: Most users should employ the simplified KSP interface for linear solvers
3118: instead of working directly with matrix algebra routines such as this.
3119: See, e.g., KSPCreate().
3121: Level: developer
3123: Concepts: matrices^Cholesky symbolic factorization
3125: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3126: MatGetOrdering()
3128: Developer Note: fortran interface is not autogenerated as the f90
3129: interface defintion cannot be generated correctly [due to MatFactorInfo]
3131: @*/
3132: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3133: {
3142: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3143: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3144: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3145: if (!(fact)->ops->choleskyfactorsymbolic) {
3146: const MatSolverPackage spackage;
3147: MatFactorGetSolverPackage(fact,&spackage);
3148: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3149: }
3150: MatCheckPreallocated(mat,2);
3152: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3153: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3154: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3155: PetscObjectStateIncrease((PetscObject)fact);
3156: return(0);
3157: }
3159: /*@C
3160: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3161: of a symmetric matrix. Call this routine after first calling
3162: MatCholeskyFactorSymbolic().
3164: Collective on Mat
3166: Input Parameters:
3167: + fact - the factor matrix obtained with MatGetFactor()
3168: . mat - the initial matrix
3169: . info - options for factorization
3170: - fact - the symbolic factor of mat
3173: Notes:
3174: Most users should employ the simplified KSP interface for linear solvers
3175: instead of working directly with matrix algebra routines such as this.
3176: See, e.g., KSPCreate().
3178: Level: developer
3180: Concepts: matrices^Cholesky numeric factorization
3182: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3184: Developer Note: fortran interface is not autogenerated as the f90
3185: interface defintion cannot be generated correctly [due to MatFactorInfo]
3187: @*/
3188: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3189: {
3197: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3198: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3199: 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);
3200: MatCheckPreallocated(mat,2);
3202: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3203: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3204: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3205: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3206: PetscObjectStateIncrease((PetscObject)fact);
3207: return(0);
3208: }
3210: /* ----------------------------------------------------------------*/
3211: /*@
3212: MatSolve - Solves A x = b, given a factored matrix.
3214: Neighbor-wise Collective on Mat and Vec
3216: Input Parameters:
3217: + mat - the factored matrix
3218: - b - the right-hand-side vector
3220: Output Parameter:
3221: . x - the result vector
3223: Notes:
3224: The vectors b and x cannot be the same. I.e., one cannot
3225: call MatSolve(A,x,x).
3227: Notes:
3228: Most users should employ the simplified KSP interface for linear solvers
3229: instead of working directly with matrix algebra routines such as this.
3230: See, e.g., KSPCreate().
3232: Level: developer
3234: Concepts: matrices^triangular solves
3236: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3237: @*/
3238: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3239: {
3249: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3250: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3251: 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);
3252: 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);
3253: 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);
3254: if (!mat->rmap->N && !mat->cmap->N) return(0);
3255: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3256: MatCheckPreallocated(mat,1);
3258: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3259: if (mat->factorerrortype) {
3260: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3261: VecSetInf(x);
3262: } else {
3263: (*mat->ops->solve)(mat,b,x);
3264: }
3265: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3266: PetscObjectStateIncrease((PetscObject)x);
3267: return(0);
3268: }
3270: static PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X, PetscBool trans)
3271: {
3273: Vec b,x;
3274: PetscInt m,N,i;
3275: PetscScalar *bb,*xx;
3276: PetscBool flg;
3279: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3280: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3281: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3282: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3284: MatDenseGetArray(B,&bb);
3285: MatDenseGetArray(X,&xx);
3286: MatGetLocalSize(B,&m,NULL); /* number local rows */
3287: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3288: MatCreateVecs(A,&x,&b);
3289: for (i=0; i<N; i++) {
3290: VecPlaceArray(b,bb + i*m);
3291: VecPlaceArray(x,xx + i*m);
3292: if (trans) {
3293: MatSolveTranspose(A,b,x);
3294: } else {
3295: MatSolve(A,b,x);
3296: }
3297: VecResetArray(x);
3298: VecResetArray(b);
3299: }
3300: VecDestroy(&b);
3301: VecDestroy(&x);
3302: MatDenseRestoreArray(B,&bb);
3303: MatDenseRestoreArray(X,&xx);
3304: return(0);
3305: }
3307: /*@
3308: MatMatSolve - Solves A X = B, given a factored matrix.
3310: Neighbor-wise Collective on Mat
3312: Input Parameters:
3313: + A - the factored matrix
3314: - B - the right-hand-side matrix (dense matrix)
3316: Output Parameter:
3317: . X - the result matrix (dense matrix)
3319: Notes:
3320: The matrices b and x cannot be the same. I.e., one cannot
3321: call MatMatSolve(A,x,x).
3323: Notes:
3324: Most users should usually employ the simplified KSP interface for linear solvers
3325: instead of working directly with matrix algebra routines such as this.
3326: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3327: at a time.
3329: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3330: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3332: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3334: Level: developer
3336: Concepts: matrices^triangular solves
3338: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3339: @*/
3340: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3341: {
3351: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3352: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3353: 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);
3354: 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);
3355: 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);
3356: if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3357: if (!A->rmap->N && !A->cmap->N) return(0);
3358: MatCheckPreallocated(A,1);
3360: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3361: if (!A->ops->matsolve) {
3362: PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3363: MatMatSolve_Basic(A,B,X,PETSC_FALSE);
3364: } else {
3365: (*A->ops->matsolve)(A,B,X);
3366: }
3367: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3368: PetscObjectStateIncrease((PetscObject)X);
3369: return(0);
3370: }
3372: /*@
3373: MatMatSolveTranspose - Solves A^T X = B, given a factored matrix.
3375: Neighbor-wise Collective on Mat
3377: Input Parameters:
3378: + A - the factored matrix
3379: - B - the right-hand-side matrix (dense matrix)
3381: Output Parameter:
3382: . X - the result matrix (dense matrix)
3384: Notes:
3385: The matrices b and x cannot be the same. I.e., one cannot
3386: call MatMatSolveTranspose(A,x,x).
3388: Notes:
3389: Most users should usually employ the simplified KSP interface for linear solvers
3390: instead of working directly with matrix algebra routines such as this.
3391: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3392: at a time.
3394: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3395: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3397: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3399: Level: developer
3401: Concepts: matrices^triangular solves
3403: .seealso: MatMatSolveTranspose(), MatLUFactor(), MatCholeskyFactor()
3404: @*/
3405: PetscErrorCode MatMatSolveTranspose(Mat A,Mat B,Mat X)
3406: {
3416: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3417: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3418: 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);
3419: 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);
3420: 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);
3421: if (X->cmap->N < B->cmap->N) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Solution matrix must have same number of columns as rhs matrix");
3422: if (!A->rmap->N && !A->cmap->N) return(0);
3423: MatCheckPreallocated(A,1);
3425: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3426: if (!A->ops->matsolvetranspose) {
3427: PetscInfo1(A,"Mat type %s using basic MatMatSolveTranspose\n",((PetscObject)A)->type_name);
3428: MatMatSolve_Basic(A,B,X,PETSC_TRUE);
3429: } else {
3430: (*A->ops->matsolvetranspose)(A,B,X);
3431: }
3432: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3433: PetscObjectStateIncrease((PetscObject)X);
3434: return(0);
3435: }
3437: /*@
3438: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3439: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3441: Neighbor-wise Collective on Mat and Vec
3443: Input Parameters:
3444: + mat - the factored matrix
3445: - b - the right-hand-side vector
3447: Output Parameter:
3448: . x - the result vector
3450: Notes:
3451: MatSolve() should be used for most applications, as it performs
3452: a forward solve followed by a backward solve.
3454: The vectors b and x cannot be the same, i.e., one cannot
3455: call MatForwardSolve(A,x,x).
3457: For matrix in seqsbaij format with block size larger than 1,
3458: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3459: MatForwardSolve() solves U^T*D y = b, and
3460: MatBackwardSolve() solves U x = y.
3461: Thus they do not provide a symmetric preconditioner.
3463: Most users should employ the simplified KSP interface for linear solvers
3464: instead of working directly with matrix algebra routines such as this.
3465: See, e.g., KSPCreate().
3467: Level: developer
3469: Concepts: matrices^forward solves
3471: .seealso: MatSolve(), MatBackwardSolve()
3472: @*/
3473: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3474: {
3484: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3485: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3486: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3487: 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);
3488: 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);
3489: 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);
3490: MatCheckPreallocated(mat,1);
3491: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3492: (*mat->ops->forwardsolve)(mat,b,x);
3493: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3494: PetscObjectStateIncrease((PetscObject)x);
3495: return(0);
3496: }
3498: /*@
3499: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3500: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3502: Neighbor-wise Collective on Mat and Vec
3504: Input Parameters:
3505: + mat - the factored matrix
3506: - b - the right-hand-side vector
3508: Output Parameter:
3509: . x - the result vector
3511: Notes:
3512: MatSolve() should be used for most applications, as it performs
3513: a forward solve followed by a backward solve.
3515: The vectors b and x cannot be the same. I.e., one cannot
3516: call MatBackwardSolve(A,x,x).
3518: For matrix in seqsbaij format with block size larger than 1,
3519: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3520: MatForwardSolve() solves U^T*D y = b, and
3521: MatBackwardSolve() solves U x = y.
3522: Thus they do not provide a symmetric preconditioner.
3524: Most users should employ the simplified KSP interface for linear solvers
3525: instead of working directly with matrix algebra routines such as this.
3526: See, e.g., KSPCreate().
3528: Level: developer
3530: Concepts: matrices^backward solves
3532: .seealso: MatSolve(), MatForwardSolve()
3533: @*/
3534: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3535: {
3545: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3546: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3547: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3548: 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);
3549: 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);
3550: if (mat->rmap->n != b->map->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Mat mat,Vec b: local dim %D %D",mat->rmap->n,b->map->n);
3551: MatCheckPreallocated(mat,1);
3553: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3554: (*mat->ops->backwardsolve)(mat,b,x);
3555: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3556: PetscObjectStateIncrease((PetscObject)x);
3557: return(0);
3558: }
3560: /*@
3561: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3563: Neighbor-wise Collective on Mat and Vec
3565: Input Parameters:
3566: + mat - the factored matrix
3567: . b - the right-hand-side vector
3568: - y - the vector to be added to
3570: Output Parameter:
3571: . x - the result vector
3573: Notes:
3574: The vectors b and x cannot be the same. I.e., one cannot
3575: call MatSolveAdd(A,x,y,x).
3577: Most users should employ the simplified KSP interface for linear solvers
3578: instead of working directly with matrix algebra routines such as this.
3579: See, e.g., KSPCreate().
3581: Level: developer
3583: Concepts: matrices^triangular solves
3585: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3586: @*/
3587: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3588: {
3589: PetscScalar one = 1.0;
3590: Vec tmp;
3602: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3603: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3604: 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);
3605: 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);
3606: 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);
3607: 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);
3608: 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);
3609: MatCheckPreallocated(mat,1);
3611: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3612: if (mat->ops->solveadd) {
3613: (*mat->ops->solveadd)(mat,b,y,x);
3614: } else {
3615: /* do the solve then the add manually */
3616: if (x != y) {
3617: MatSolve(mat,b,x);
3618: VecAXPY(x,one,y);
3619: } else {
3620: VecDuplicate(x,&tmp);
3621: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3622: VecCopy(x,tmp);
3623: MatSolve(mat,b,x);
3624: VecAXPY(x,one,tmp);
3625: VecDestroy(&tmp);
3626: }
3627: }
3628: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3629: PetscObjectStateIncrease((PetscObject)x);
3630: return(0);
3631: }
3633: /*@
3634: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3636: Neighbor-wise Collective on Mat and Vec
3638: Input Parameters:
3639: + mat - the factored matrix
3640: - b - the right-hand-side vector
3642: Output Parameter:
3643: . x - the result vector
3645: Notes:
3646: The vectors b and x cannot be the same. I.e., one cannot
3647: call MatSolveTranspose(A,x,x).
3649: Most users should employ the simplified KSP interface for linear solvers
3650: instead of working directly with matrix algebra routines such as this.
3651: See, e.g., KSPCreate().
3653: Level: developer
3655: Concepts: matrices^triangular solves
3657: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3658: @*/
3659: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3660: {
3670: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3671: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3672: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3673: 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);
3674: 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);
3675: MatCheckPreallocated(mat,1);
3676: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3677: if (mat->factorerrortype) {
3678: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3679: VecSetInf(x);
3680: } else {
3681: (*mat->ops->solvetranspose)(mat,b,x);
3682: }
3683: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3684: PetscObjectStateIncrease((PetscObject)x);
3685: return(0);
3686: }
3688: /*@
3689: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3690: factored matrix.
3692: Neighbor-wise Collective on Mat and Vec
3694: Input Parameters:
3695: + mat - the factored matrix
3696: . b - the right-hand-side vector
3697: - y - the vector to be added to
3699: Output Parameter:
3700: . x - the result vector
3702: Notes:
3703: The vectors b and x cannot be the same. I.e., one cannot
3704: call MatSolveTransposeAdd(A,x,y,x).
3706: Most users should employ the simplified KSP interface for linear solvers
3707: instead of working directly with matrix algebra routines such as this.
3708: See, e.g., KSPCreate().
3710: Level: developer
3712: Concepts: matrices^triangular solves
3714: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3715: @*/
3716: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3717: {
3718: PetscScalar one = 1.0;
3720: Vec tmp;
3731: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3732: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3733: 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);
3734: 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);
3735: 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);
3736: 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);
3737: MatCheckPreallocated(mat,1);
3739: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3740: if (mat->ops->solvetransposeadd) {
3741: if (mat->factorerrortype) {
3742: PetscInfo1(mat,"MatFactorError %D\n",mat->factorerrortype);
3743: VecSetInf(x);
3744: } else {
3745: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3746: }
3747: } else {
3748: /* do the solve then the add manually */
3749: if (x != y) {
3750: MatSolveTranspose(mat,b,x);
3751: VecAXPY(x,one,y);
3752: } else {
3753: VecDuplicate(x,&tmp);
3754: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3755: VecCopy(x,tmp);
3756: MatSolveTranspose(mat,b,x);
3757: VecAXPY(x,one,tmp);
3758: VecDestroy(&tmp);
3759: }
3760: }
3761: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3762: PetscObjectStateIncrease((PetscObject)x);
3763: return(0);
3764: }
3765: /* ----------------------------------------------------------------*/
3767: /*@
3768: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3770: Neighbor-wise Collective on Mat and Vec
3772: Input Parameters:
3773: + mat - the matrix
3774: . b - the right hand side
3775: . omega - the relaxation factor
3776: . flag - flag indicating the type of SOR (see below)
3777: . shift - diagonal shift
3778: . its - the number of iterations
3779: - lits - the number of local iterations
3781: Output Parameters:
3782: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3784: SOR Flags:
3785: . SOR_FORWARD_SWEEP - forward SOR
3786: . SOR_BACKWARD_SWEEP - backward SOR
3787: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3788: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3789: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3790: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3791: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3792: upper/lower triangular part of matrix to
3793: vector (with omega)
3794: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3796: Notes:
3797: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3798: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3799: on each processor.
3801: Application programmers will not generally use MatSOR() directly,
3802: but instead will employ the KSP/PC interface.
3804: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3806: Notes for Advanced Users:
3807: The flags are implemented as bitwise inclusive or operations.
3808: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3809: to specify a zero initial guess for SSOR.
3811: Most users should employ the simplified KSP interface for linear solvers
3812: instead of working directly with matrix algebra routines such as this.
3813: See, e.g., KSPCreate().
3815: Vectors x and b CANNOT be the same
3817: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3819: Level: developer
3821: Concepts: matrices^relaxation
3822: Concepts: matrices^SOR
3823: Concepts: matrices^Gauss-Seidel
3825: @*/
3826: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3827: {
3837: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3838: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3839: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3840: 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);
3841: 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);
3842: 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);
3843: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3844: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3845: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3847: MatCheckPreallocated(mat,1);
3848: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3849: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3850: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3851: PetscObjectStateIncrease((PetscObject)x);
3852: return(0);
3853: }
3855: /*
3856: Default matrix copy routine.
3857: */
3858: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3859: {
3860: PetscErrorCode ierr;
3861: PetscInt i,rstart = 0,rend = 0,nz;
3862: const PetscInt *cwork;
3863: const PetscScalar *vwork;
3866: if (B->assembled) {
3867: MatZeroEntries(B);
3868: }
3869: MatGetOwnershipRange(A,&rstart,&rend);
3870: for (i=rstart; i<rend; i++) {
3871: MatGetRow(A,i,&nz,&cwork,&vwork);
3872: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3873: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3874: }
3875: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3876: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3877: return(0);
3878: }
3880: /*@
3881: MatCopy - Copys a matrix to another matrix.
3883: Collective on Mat
3885: Input Parameters:
3886: + A - the matrix
3887: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3889: Output Parameter:
3890: . B - where the copy is put
3892: Notes:
3893: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3894: same nonzero pattern or the routine will crash.
3896: MatCopy() copies the matrix entries of a matrix to another existing
3897: matrix (after first zeroing the second matrix). A related routine is
3898: MatConvert(), which first creates a new matrix and then copies the data.
3900: Level: intermediate
3902: Concepts: matrices^copying
3904: .seealso: MatConvert(), MatDuplicate()
3906: @*/
3907: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3908: {
3910: PetscInt i;
3918: MatCheckPreallocated(B,2);
3919: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3920: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3921: 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);
3922: MatCheckPreallocated(A,1);
3924: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3925: if (A->ops->copy) {
3926: (*A->ops->copy)(A,B,str);
3927: } else { /* generic conversion */
3928: MatCopy_Basic(A,B,str);
3929: }
3931: B->stencil.dim = A->stencil.dim;
3932: B->stencil.noc = A->stencil.noc;
3933: for (i=0; i<=A->stencil.dim; i++) {
3934: B->stencil.dims[i] = A->stencil.dims[i];
3935: B->stencil.starts[i] = A->stencil.starts[i];
3936: }
3938: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3939: PetscObjectStateIncrease((PetscObject)B);
3940: return(0);
3941: }
3943: /*@C
3944: MatConvert - Converts a matrix to another matrix, either of the same
3945: or different type.
3947: Collective on Mat
3949: Input Parameters:
3950: + mat - the matrix
3951: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3952: same type as the original matrix.
3953: - reuse - denotes if the destination matrix is to be created or reused.
3954: Use MAT_INPLACE_MATRIX for inplace conversion (that is when you want the input mat to be changed to contain the matrix in the new format), otherwise use
3955: MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX (can only be used after the first call was made with MAT_INITIAL_MATRIX, causes the matrix space in M to be reused).
3957: Output Parameter:
3958: . M - pointer to place new matrix
3960: Notes:
3961: MatConvert() first creates a new matrix and then copies the data from
3962: the first matrix. A related routine is MatCopy(), which copies the matrix
3963: entries of one matrix to another already existing matrix context.
3965: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3966: the MPI communicator of the generated matrix is always the same as the communicator
3967: of the input matrix.
3969: Level: intermediate
3971: Concepts: matrices^converting between storage formats
3973: .seealso: MatCopy(), MatDuplicate()
3974: @*/
3975: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3976: {
3978: PetscBool sametype,issame,flg;
3979: char convname[256],mtype[256];
3980: Mat B;
3986: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3987: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3988: MatCheckPreallocated(mat,1);
3989: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3991: PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3992: if (flg) {
3993: newtype = mtype;
3994: }
3995: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3996: PetscStrcmp(newtype,"same",&issame);
3997: if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3998: if ((reuse == MAT_REUSE_MATRIX) && (mat == *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_REUSE_MATRIX means reuse matrix in final argument, perhaps you mean MAT_INPLACE_MATRIX");
4000: if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);
4002: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
4003: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
4004: } else {
4005: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
4006: const char *prefix[3] = {"seq","mpi",""};
4007: PetscInt i;
4008: /*
4009: Order of precedence:
4010: 1) See if a specialized converter is known to the current matrix.
4011: 2) See if a specialized converter is known to the desired matrix class.
4012: 3) See if a good general converter is registered for the desired class
4013: (as of 6/27/03 only MATMPIADJ falls into this category).
4014: 4) See if a good general converter is known for the current matrix.
4015: 5) Use a really basic converter.
4016: */
4018: /* 1) See if a specialized converter is known to the current matrix and the desired class */
4019: for (i=0; i<3; i++) {
4020: PetscStrcpy(convname,"MatConvert_");
4021: PetscStrcat(convname,((PetscObject)mat)->type_name);
4022: PetscStrcat(convname,"_");
4023: PetscStrcat(convname,prefix[i]);
4024: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
4025: PetscStrcat(convname,"_C");
4026: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
4027: if (conv) goto foundconv;
4028: }
4030: /* 2) See if a specialized converter is known to the desired matrix class. */
4031: MatCreate(PetscObjectComm((PetscObject)mat),&B);
4032: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
4033: MatSetType(B,newtype);
4034: for (i=0; i<3; i++) {
4035: PetscStrcpy(convname,"MatConvert_");
4036: PetscStrcat(convname,((PetscObject)mat)->type_name);
4037: PetscStrcat(convname,"_");
4038: PetscStrcat(convname,prefix[i]);
4039: PetscStrcat(convname,newtype);
4040: PetscStrcat(convname,"_C");
4041: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
4042: if (conv) {
4043: MatDestroy(&B);
4044: goto foundconv;
4045: }
4046: }
4048: /* 3) See if a good general converter is registered for the desired class */
4049: conv = B->ops->convertfrom;
4050: MatDestroy(&B);
4051: if (conv) goto foundconv;
4053: /* 4) See if a good general converter is known for the current matrix */
4054: if (mat->ops->convert) {
4055: conv = mat->ops->convert;
4056: }
4057: if (conv) goto foundconv;
4059: /* 5) Use a really basic converter. */
4060: conv = MatConvert_Basic;
4062: foundconv:
4063: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4064: (*conv)(mat,newtype,reuse,M);
4065: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4066: }
4067: PetscObjectStateIncrease((PetscObject)*M);
4069: /* Copy Mat options */
4070: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
4071: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
4072: return(0);
4073: }
4075: /*@C
4076: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
4078: Not Collective
4080: Input Parameter:
4081: . mat - the matrix, must be a factored matrix
4083: Output Parameter:
4084: . type - the string name of the package (do not free this string)
4086: Notes:
4087: In Fortran you pass in a empty string and the package name will be copied into it.
4088: (Make sure the string is long enough)
4090: Level: intermediate
4092: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4093: @*/
4094: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4095: {
4096: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4101: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4102: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4103: if (!conv) {
4104: *type = MATSOLVERPETSC;
4105: } else {
4106: (*conv)(mat,type);
4107: }
4108: return(0);
4109: }
4111: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4112: struct _MatSolverPackageForSpecifcType {
4113: MatType mtype;
4114: PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*);
4115: MatSolverPackageForSpecifcType next;
4116: };
4118: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4119: struct _MatSolverPackageHolder {
4120: char *name;
4121: MatSolverPackageForSpecifcType handlers;
4122: MatSolverPackageHolder next;
4123: };
4125: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4127: /*@C
4128: MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4130: Input Parameters:
4131: + package - name of the package, for example petsc or superlu
4132: . mtype - the matrix type that works with this package
4133: . ftype - the type of factorization supported by the package
4134: - getfactor - routine that will create the factored matrix ready to be used
4136: Level: intermediate
4138: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4139: @*/
4140: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4141: {
4142: PetscErrorCode ierr;
4143: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4144: PetscBool flg;
4145: MatSolverPackageForSpecifcType inext,iprev = NULL;
4148: if (!next) {
4149: PetscNew(&MatSolverPackageHolders);
4150: PetscStrallocpy(package,&MatSolverPackageHolders->name);
4151: PetscNew(&MatSolverPackageHolders->handlers);
4152: PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4153: MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4154: return(0);
4155: }
4156: while (next) {
4157: PetscStrcasecmp(package,next->name,&flg);
4158: if (flg) {
4159: if (!next->handlers) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatSolverPackageHolder is missing handlers");
4160: inext = next->handlers;
4161: while (inext) {
4162: PetscStrcasecmp(mtype,inext->mtype,&flg);
4163: if (flg) {
4164: inext->getfactor[(int)ftype-1] = getfactor;
4165: return(0);
4166: }
4167: iprev = inext;
4168: inext = inext->next;
4169: }
4170: PetscNew(&iprev->next);
4171: PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4172: iprev->next->getfactor[(int)ftype-1] = getfactor;
4173: return(0);
4174: }
4175: prev = next;
4176: next = next->next;
4177: }
4178: PetscNew(&prev->next);
4179: PetscStrallocpy(package,&prev->next->name);
4180: PetscNew(&prev->next->handlers);
4181: PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4182: prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4183: return(0);
4184: }
4186: /*@C
4187: MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4189: Input Parameters:
4190: + package - name of the package, for example petsc or superlu
4191: . ftype - the type of factorization supported by the package
4192: - mtype - the matrix type that works with this package
4194: Output Parameters:
4195: + foundpackage - PETSC_TRUE if the package was registered
4196: . foundmtype - PETSC_TRUE if the package supports the requested mtype
4197: - getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4199: Level: intermediate
4201: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4202: @*/
4203: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4204: {
4205: PetscErrorCode ierr;
4206: MatSolverPackageHolder next = MatSolverPackageHolders;
4207: PetscBool flg;
4208: MatSolverPackageForSpecifcType inext;
4211: if (foundpackage) *foundpackage = PETSC_FALSE;
4212: if (foundmtype) *foundmtype = PETSC_FALSE;
4213: if (getfactor) *getfactor = NULL;
4215: if (package) {
4216: while (next) {
4217: PetscStrcasecmp(package,next->name,&flg);
4218: if (flg) {
4219: if (foundpackage) *foundpackage = PETSC_TRUE;
4220: inext = next->handlers;
4221: while (inext) {
4222: PetscStrbeginswith(mtype,inext->mtype,&flg);
4223: if (flg) {
4224: if (foundmtype) *foundmtype = PETSC_TRUE;
4225: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4226: return(0);
4227: }
4228: inext = inext->next;
4229: }
4230: }
4231: next = next->next;
4232: }
4233: } else {
4234: while (next) {
4235: inext = next->handlers;
4236: while (inext) {
4237: PetscStrbeginswith(mtype,inext->mtype,&flg);
4238: if (flg && inext->getfactor[(int)ftype-1]) {
4239: if (foundpackage) *foundpackage = PETSC_TRUE;
4240: if (foundmtype) *foundmtype = PETSC_TRUE;
4241: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4242: return(0);
4243: }
4244: inext = inext->next;
4245: }
4246: next = next->next;
4247: }
4248: }
4249: return(0);
4250: }
4252: PetscErrorCode MatSolverPackageDestroy(void)
4253: {
4254: PetscErrorCode ierr;
4255: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4256: MatSolverPackageForSpecifcType inext,iprev;
4259: while (next) {
4260: PetscFree(next->name);
4261: inext = next->handlers;
4262: while (inext) {
4263: PetscFree(inext->mtype);
4264: iprev = inext;
4265: inext = inext->next;
4266: PetscFree(iprev);
4267: }
4268: prev = next;
4269: next = next->next;
4270: PetscFree(prev);
4271: }
4272: MatSolverPackageHolders = NULL;
4273: return(0);
4274: }
4276: /*@C
4277: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4279: Collective on Mat
4281: Input Parameters:
4282: + mat - the matrix
4283: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4284: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4286: Output Parameters:
4287: . f - the factor matrix used with MatXXFactorSymbolic() calls
4289: Notes:
4290: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4291: such as pastix, superlu, mumps etc.
4293: PETSc must have been ./configure to use the external solver, using the option --download-package
4295: Level: intermediate
4297: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4298: @*/
4299: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4300: {
4301: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4302: PetscBool foundpackage,foundmtype;
4308: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4309: MatCheckPreallocated(mat,1);
4311: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4312: if (!foundpackage) {
4313: if (type) {
4314: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4315: } else {
4316: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4317: }
4318: }
4320: if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4321: if (!conv) SETERRQ3(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support factorization type %s for matrix type %s",type,MatFactorTypes[ftype],((PetscObject)mat)->type_name);
4323: (*conv)(mat,ftype,f);
4324: return(0);
4325: }
4327: /*@C
4328: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4330: Not Collective
4332: Input Parameters:
4333: + mat - the matrix
4334: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4335: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4337: Output Parameter:
4338: . flg - PETSC_TRUE if the factorization is available
4340: Notes:
4341: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4342: such as pastix, superlu, mumps etc.
4344: PETSc must have been ./configure to use the external solver, using the option --download-package
4346: Level: intermediate
4348: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4349: @*/
4350: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
4351: {
4352: PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4358: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4359: MatCheckPreallocated(mat,1);
4361: *flg = PETSC_FALSE;
4362: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4363: if (gconv) {
4364: *flg = PETSC_TRUE;
4365: }
4366: return(0);
4367: }
4369: #include <petscdmtypes.h>
4371: /*@
4372: MatDuplicate - Duplicates a matrix including the non-zero structure.
4374: Collective on Mat
4376: Input Parameters:
4377: + mat - the matrix
4378: - op - One of MAT_DO_NOT_COPY_VALUES, MAT_COPY_VALUES, or MAT_SHARE_NONZERO_PATTERN.
4379: See the manual page for MatDuplicateOption for an explanation of these options.
4381: Output Parameter:
4382: . M - pointer to place new matrix
4384: Level: intermediate
4386: Concepts: matrices^duplicating
4388: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4390: .seealso: MatCopy(), MatConvert(), MatDuplicateOption
4391: @*/
4392: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4393: {
4395: Mat B;
4396: PetscInt i;
4397: DM dm;
4403: if (op == MAT_COPY_VALUES && !mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"MAT_COPY_VALUES not allowed for unassembled matrix");
4404: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4405: MatCheckPreallocated(mat,1);
4407: *M = 0;
4408: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4409: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4410: (*mat->ops->duplicate)(mat,op,M);
4411: B = *M;
4413: B->stencil.dim = mat->stencil.dim;
4414: B->stencil.noc = mat->stencil.noc;
4415: for (i=0; i<=mat->stencil.dim; i++) {
4416: B->stencil.dims[i] = mat->stencil.dims[i];
4417: B->stencil.starts[i] = mat->stencil.starts[i];
4418: }
4420: B->nooffproczerorows = mat->nooffproczerorows;
4421: B->nooffprocentries = mat->nooffprocentries;
4423: PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4424: if (dm) {
4425: PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4426: }
4427: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4428: PetscObjectStateIncrease((PetscObject)B);
4429: return(0);
4430: }
4432: /*@
4433: MatGetDiagonal - Gets the diagonal of a matrix.
4435: Logically Collective on Mat and Vec
4437: Input Parameters:
4438: + mat - the matrix
4439: - v - the vector for storing the diagonal
4441: Output Parameter:
4442: . v - the diagonal of the matrix
4444: Level: intermediate
4446: Note:
4447: Currently only correct in parallel for square matrices.
4449: Concepts: matrices^accessing diagonals
4451: .seealso: MatGetRow(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs()
4452: @*/
4453: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4454: {
4461: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4462: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4463: MatCheckPreallocated(mat,1);
4465: (*mat->ops->getdiagonal)(mat,v);
4466: PetscObjectStateIncrease((PetscObject)v);
4467: return(0);
4468: }
4470: /*@C
4471: MatGetRowMin - Gets the minimum value (of the real part) of each
4472: row of the matrix
4474: Logically Collective on Mat and Vec
4476: Input Parameters:
4477: . mat - the matrix
4479: Output Parameter:
4480: + v - the vector for storing the maximums
4481: - idx - the indices of the column found for each row (optional)
4483: Level: intermediate
4485: Notes: The result of this call are the same as if one converted the matrix to dense format
4486: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4488: This code is only implemented for a couple of matrix formats.
4490: Concepts: matrices^getting row maximums
4492: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(),
4493: MatGetRowMax()
4494: @*/
4495: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4496: {
4503: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4504: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4505: MatCheckPreallocated(mat,1);
4507: (*mat->ops->getrowmin)(mat,v,idx);
4508: PetscObjectStateIncrease((PetscObject)v);
4509: return(0);
4510: }
4512: /*@C
4513: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4514: row of the matrix
4516: Logically Collective on Mat and Vec
4518: Input Parameters:
4519: . mat - the matrix
4521: Output Parameter:
4522: + v - the vector for storing the minimums
4523: - idx - the indices of the column found for each row (or NULL if not needed)
4525: Level: intermediate
4527: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4528: row is 0 (the first column).
4530: This code is only implemented for a couple of matrix formats.
4532: Concepts: matrices^getting row maximums
4534: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4535: @*/
4536: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4537: {
4544: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4545: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4546: MatCheckPreallocated(mat,1);
4547: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4549: (*mat->ops->getrowminabs)(mat,v,idx);
4550: PetscObjectStateIncrease((PetscObject)v);
4551: return(0);
4552: }
4554: /*@C
4555: MatGetRowMax - Gets the maximum value (of the real part) of each
4556: row of the matrix
4558: Logically Collective on Mat and Vec
4560: Input Parameters:
4561: . mat - the matrix
4563: Output Parameter:
4564: + v - the vector for storing the maximums
4565: - idx - the indices of the column found for each row (optional)
4567: Level: intermediate
4569: Notes: The result of this call are the same as if one converted the matrix to dense format
4570: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4572: This code is only implemented for a couple of matrix formats.
4574: Concepts: matrices^getting row maximums
4576: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4577: @*/
4578: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4579: {
4586: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4587: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4588: MatCheckPreallocated(mat,1);
4590: (*mat->ops->getrowmax)(mat,v,idx);
4591: PetscObjectStateIncrease((PetscObject)v);
4592: return(0);
4593: }
4595: /*@C
4596: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4597: row of the matrix
4599: Logically Collective on Mat and Vec
4601: Input Parameters:
4602: . mat - the matrix
4604: Output Parameter:
4605: + v - the vector for storing the maximums
4606: - idx - the indices of the column found for each row (or NULL if not needed)
4608: Level: intermediate
4610: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4611: row is 0 (the first column).
4613: This code is only implemented for a couple of matrix formats.
4615: Concepts: matrices^getting row maximums
4617: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4618: @*/
4619: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4620: {
4627: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4628: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4629: MatCheckPreallocated(mat,1);
4630: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4632: (*mat->ops->getrowmaxabs)(mat,v,idx);
4633: PetscObjectStateIncrease((PetscObject)v);
4634: return(0);
4635: }
4637: /*@
4638: MatGetRowSum - Gets the sum of each row of the matrix
4640: Logically or Neighborhood Collective on Mat and Vec
4642: Input Parameters:
4643: . mat - the matrix
4645: Output Parameter:
4646: . v - the vector for storing the sum of rows
4648: Level: intermediate
4650: Notes: This code is slow since it is not currently specialized for different formats
4652: Concepts: matrices^getting row sums
4654: .seealso: MatGetDiagonal(), MatCreateSubMatrices(), MatCreateSubmatrix(), MatGetRowMax(), MatGetRowMin()
4655: @*/
4656: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4657: {
4658: Vec ones;
4665: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4666: MatCheckPreallocated(mat,1);
4667: MatCreateVecs(mat,NULL,&ones);
4668: VecSet(ones,1.);
4669: MatMult(mat,ones,v);
4670: VecDestroy(&ones);
4671: return(0);
4672: }
4674: /*@
4675: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4677: Collective on Mat
4679: Input Parameter:
4680: + mat - the matrix to transpose
4681: - reuse - either MAT_INITIAL_MATRIX, MAT_REUSE_MATRIX, or MAT_INPLACE_MATRIX
4683: Output Parameters:
4684: . B - the transpose
4686: Notes:
4687: If you use MAT_INPLACE_MATRIX then you must pass in &mat for B
4689: MAT_REUSE_MATRIX causes the B matrix from a previous call to this function with MAT_INITIAL_MATRIX to be used
4691: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4693: Level: intermediate
4695: Concepts: matrices^transposing
4697: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4698: @*/
4699: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4700: {
4706: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4707: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4708: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4709: if (reuse == MAT_INPLACE_MATRIX && mat != *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires last matrix to match first");
4710: if (reuse == MAT_REUSE_MATRIX && mat == *B) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Perhaps you mean MAT_INPLACE_MATRIX");
4711: MatCheckPreallocated(mat,1);
4713: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4714: (*mat->ops->transpose)(mat,reuse,B);
4715: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4716: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4717: return(0);
4718: }
4720: /*@
4721: MatIsTranspose - Test whether a matrix is another one's transpose,
4722: or its own, in which case it tests symmetry.
4724: Collective on Mat
4726: Input Parameter:
4727: + A - the matrix to test
4728: - B - the matrix to test against, this can equal the first parameter
4730: Output Parameters:
4731: . flg - the result
4733: Notes:
4734: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4735: has a running time of the order of the number of nonzeros; the parallel
4736: test involves parallel copies of the block-offdiagonal parts of the matrix.
4738: Level: intermediate
4740: Concepts: matrices^transposing, matrix^symmetry
4742: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4743: @*/
4744: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4745: {
4746: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4752: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4753: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4754: *flg = PETSC_FALSE;
4755: if (f && g) {
4756: if (f == g) {
4757: (*f)(A,B,tol,flg);
4758: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4759: } else {
4760: MatType mattype;
4761: if (!f) {
4762: MatGetType(A,&mattype);
4763: } else {
4764: MatGetType(B,&mattype);
4765: }
4766: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4767: }
4768: return(0);
4769: }
4771: /*@
4772: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4774: Collective on Mat
4776: Input Parameter:
4777: + mat - the matrix to transpose and complex conjugate
4778: - reuse - MAT_INITIAL_MATRIX to create a new matrix, MAT_INPLACE_MATRIX to reuse the first argument to store the transpose
4780: Output Parameters:
4781: . B - the Hermitian
4783: Level: intermediate
4785: Concepts: matrices^transposing, complex conjugatex
4787: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4788: @*/
4789: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4790: {
4794: MatTranspose(mat,reuse,B);
4795: #if defined(PETSC_USE_COMPLEX)
4796: MatConjugate(*B);
4797: #endif
4798: return(0);
4799: }
4801: /*@
4802: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4804: Collective on Mat
4806: Input Parameter:
4807: + A - the matrix to test
4808: - B - the matrix to test against, this can equal the first parameter
4810: Output Parameters:
4811: . flg - the result
4813: Notes:
4814: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4815: has a running time of the order of the number of nonzeros; the parallel
4816: test involves parallel copies of the block-offdiagonal parts of the matrix.
4818: Level: intermediate
4820: Concepts: matrices^transposing, matrix^symmetry
4822: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4823: @*/
4824: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4825: {
4826: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4832: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4833: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4834: if (f && g) {
4835: if (f==g) {
4836: (*f)(A,B,tol,flg);
4837: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4838: }
4839: return(0);
4840: }
4842: /*@
4843: MatPermute - Creates a new matrix with rows and columns permuted from the
4844: original.
4846: Collective on Mat
4848: Input Parameters:
4849: + mat - the matrix to permute
4850: . row - row permutation, each processor supplies only the permutation for its rows
4851: - col - column permutation, each processor supplies only the permutation for its columns
4853: Output Parameters:
4854: . B - the permuted matrix
4856: Level: advanced
4858: Note:
4859: The index sets map from row/col of permuted matrix to row/col of original matrix.
4860: The index sets should be on the same communicator as Mat and have the same local sizes.
4862: Concepts: matrices^permuting
4864: .seealso: MatGetOrdering(), ISAllGather()
4866: @*/
4867: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4868: {
4877: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4878: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4879: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4880: MatCheckPreallocated(mat,1);
4882: (*mat->ops->permute)(mat,row,col,B);
4883: PetscObjectStateIncrease((PetscObject)*B);
4884: return(0);
4885: }
4887: /*@
4888: MatEqual - Compares two matrices.
4890: Collective on Mat
4892: Input Parameters:
4893: + A - the first matrix
4894: - B - the second matrix
4896: Output Parameter:
4897: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4899: Level: intermediate
4901: Concepts: matrices^equality between
4902: @*/
4903: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4904: {
4914: MatCheckPreallocated(B,2);
4915: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4916: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4917: 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);
4918: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4919: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4920: 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);
4921: MatCheckPreallocated(A,1);
4923: (*A->ops->equal)(A,B,flg);
4924: return(0);
4925: }
4927: /*@C
4928: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4929: matrices that are stored as vectors. Either of the two scaling
4930: matrices can be NULL.
4932: Collective on Mat
4934: Input Parameters:
4935: + mat - the matrix to be scaled
4936: . l - the left scaling vector (or NULL)
4937: - r - the right scaling vector (or NULL)
4939: Notes:
4940: MatDiagonalScale() computes A = LAR, where
4941: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4942: The L scales the rows of the matrix, the R scales the columns of the matrix.
4944: Level: intermediate
4946: Concepts: matrices^diagonal scaling
4947: Concepts: diagonal scaling of matrices
4949: .seealso: MatScale()
4950: @*/
4951: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4952: {
4958: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4961: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4962: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4963: MatCheckPreallocated(mat,1);
4965: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4966: (*mat->ops->diagonalscale)(mat,l,r);
4967: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4968: PetscObjectStateIncrease((PetscObject)mat);
4969: #if defined(PETSC_HAVE_CUSP)
4970: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4971: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4972: }
4973: #elif defined(PETSC_HAVE_VIENNACL)
4974: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4975: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4976: }
4977: #elif defined(PETSC_HAVE_VECCUDA)
4978: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4979: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4980: }
4981: #endif
4982: return(0);
4983: }
4985: /*@
4986: MatScale - Scales all elements of a matrix by a given number.
4988: Logically Collective on Mat
4990: Input Parameters:
4991: + mat - the matrix to be scaled
4992: - a - the scaling value
4994: Output Parameter:
4995: . mat - the scaled matrix
4997: Level: intermediate
4999: Concepts: matrices^scaling all entries
5001: .seealso: MatDiagonalScale()
5002: @*/
5003: PetscErrorCode MatScale(Mat mat,PetscScalar a)
5004: {
5010: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5011: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5012: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5014: MatCheckPreallocated(mat,1);
5016: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
5017: if (a != (PetscScalar)1.0) {
5018: (*mat->ops->scale)(mat,a);
5019: PetscObjectStateIncrease((PetscObject)mat);
5020: #if defined(PETSC_HAVE_CUSP)
5021: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5022: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5023: }
5024: #elif defined(PETSC_HAVE_VIENNACL)
5025: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5026: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5027: }
5028: #elif defined(PETSC_HAVE_VECCUDA)
5029: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5030: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5031: }
5032: #endif
5033: }
5034: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
5035: return(0);
5036: }
5038: /*@
5039: MatNorm - Calculates various norms of a matrix.
5041: Collective on Mat
5043: Input Parameters:
5044: + mat - the matrix
5045: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5047: Output Parameters:
5048: . nrm - the resulting norm
5050: Level: intermediate
5052: Concepts: matrices^norm
5053: Concepts: norm^of matrix
5054: @*/
5055: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5056: {
5064: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5065: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5066: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5067: MatCheckPreallocated(mat,1);
5069: (*mat->ops->norm)(mat,type,nrm);
5070: return(0);
5071: }
5073: /*
5074: This variable is used to prevent counting of MatAssemblyBegin() that
5075: are called from within a MatAssemblyEnd().
5076: */
5077: static PetscInt MatAssemblyEnd_InUse = 0;
5078: /*@
5079: MatAssemblyBegin - Begins assembling the matrix. This routine should
5080: be called after completing all calls to MatSetValues().
5082: Collective on Mat
5084: Input Parameters:
5085: + mat - the matrix
5086: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5088: Notes:
5089: MatSetValues() generally caches the values. The matrix is ready to
5090: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5091: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5092: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5093: using the matrix.
5095: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5096: 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
5097: a global collective operation requring all processes that share the matrix.
5099: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5100: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5101: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5103: Level: beginner
5105: Concepts: matrices^assembling
5107: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5108: @*/
5109: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5110: {
5116: MatCheckPreallocated(mat,1);
5117: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5118: if (mat->assembled) {
5119: mat->was_assembled = PETSC_TRUE;
5120: mat->assembled = PETSC_FALSE;
5121: }
5122: if (!MatAssemblyEnd_InUse) {
5123: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5124: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5125: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5126: } else if (mat->ops->assemblybegin) {
5127: (*mat->ops->assemblybegin)(mat,type);
5128: }
5129: return(0);
5130: }
5132: /*@
5133: MatAssembled - Indicates if a matrix has been assembled and is ready for
5134: use; for example, in matrix-vector product.
5136: Not Collective
5138: Input Parameter:
5139: . mat - the matrix
5141: Output Parameter:
5142: . assembled - PETSC_TRUE or PETSC_FALSE
5144: Level: advanced
5146: Concepts: matrices^assembled?
5148: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5149: @*/
5150: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5151: {
5156: *assembled = mat->assembled;
5157: return(0);
5158: }
5160: /*@
5161: MatAssemblyEnd - Completes assembling the matrix. This routine should
5162: be called after MatAssemblyBegin().
5164: Collective on Mat
5166: Input Parameters:
5167: + mat - the matrix
5168: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5170: Options Database Keys:
5171: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5172: . -mat_view ::ascii_info_detail - Prints more detailed info
5173: . -mat_view - Prints matrix in ASCII format
5174: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5175: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5176: . -display <name> - Sets display name (default is host)
5177: . -draw_pause <sec> - Sets number of seconds to pause after display
5178: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 12 Using MATLAB with PETSc )
5179: . -viewer_socket_machine <machine> - Machine to use for socket
5180: . -viewer_socket_port <port> - Port number to use for socket
5181: - -mat_view binary:filename[:append] - Save matrix to file in binary format
5183: Notes:
5184: MatSetValues() generally caches the values. The matrix is ready to
5185: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5186: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5187: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5188: using the matrix.
5190: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5191: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5192: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5194: Level: beginner
5196: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5197: @*/
5198: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5199: {
5200: PetscErrorCode ierr;
5201: static PetscInt inassm = 0;
5202: PetscBool flg = PETSC_FALSE;
5208: inassm++;
5209: MatAssemblyEnd_InUse++;
5210: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5211: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5212: if (mat->ops->assemblyend) {
5213: (*mat->ops->assemblyend)(mat,type);
5214: }
5215: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5216: } else if (mat->ops->assemblyend) {
5217: (*mat->ops->assemblyend)(mat,type);
5218: }
5220: /* Flush assembly is not a true assembly */
5221: if (type != MAT_FLUSH_ASSEMBLY) {
5222: mat->assembled = PETSC_TRUE; mat->num_ass++;
5223: }
5224: mat->insertmode = NOT_SET_VALUES;
5225: MatAssemblyEnd_InUse--;
5226: PetscObjectStateIncrease((PetscObject)mat);
5227: if (!mat->symmetric_eternal) {
5228: mat->symmetric_set = PETSC_FALSE;
5229: mat->hermitian_set = PETSC_FALSE;
5230: mat->structurally_symmetric_set = PETSC_FALSE;
5231: }
5232: #if defined(PETSC_HAVE_CUSP)
5233: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5234: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5235: }
5236: #elif defined(PETSC_HAVE_VIENNACL)
5237: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5238: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5239: }
5240: #elif defined(PETSC_HAVE_VECCUDA)
5241: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5242: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5243: }
5244: #endif
5245: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5246: MatViewFromOptions(mat,NULL,"-mat_view");
5248: if (mat->checksymmetryonassembly) {
5249: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5250: if (flg) {
5251: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5252: } else {
5253: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5254: }
5255: }
5256: if (mat->nullsp && mat->checknullspaceonassembly) {
5257: MatNullSpaceTest(mat->nullsp,mat,NULL);
5258: }
5259: }
5260: inassm--;
5261: return(0);
5262: }
5264: /*@
5265: MatSetOption - Sets a parameter option for a matrix. Some options
5266: may be specific to certain storage formats. Some options
5267: determine how values will be inserted (or added). Sorted,
5268: row-oriented input will generally assemble the fastest. The default
5269: is row-oriented.
5271: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5273: Input Parameters:
5274: + mat - the matrix
5275: . option - the option, one of those listed below (and possibly others),
5276: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5278: Options Describing Matrix Structure:
5279: + MAT_SPD - symmetric positive definite
5280: . MAT_SYMMETRIC - symmetric in terms of both structure and value
5281: . MAT_HERMITIAN - transpose is the complex conjugation
5282: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5283: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5284: you set to be kept with all future use of the matrix
5285: including after MatAssemblyBegin/End() which could
5286: potentially change the symmetry structure, i.e. you
5287: KNOW the matrix will ALWAYS have the property you set.
5290: Options For Use with MatSetValues():
5291: Insert a logically dense subblock, which can be
5292: . MAT_ROW_ORIENTED - row-oriented (default)
5294: Note these options reflect the data you pass in with MatSetValues(); it has
5295: nothing to do with how the data is stored internally in the matrix
5296: data structure.
5298: When (re)assembling a matrix, we can restrict the input for
5299: efficiency/debugging purposes. These options include:
5300: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5301: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5302: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5303: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5304: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5305: . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5306: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5307: performance for very large process counts.
5308: - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5309: of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5310: functions, instead sending only neighbor messages.
5312: Notes:
5313: Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5315: Some options are relevant only for particular matrix types and
5316: are thus ignored by others. Other options are not supported by
5317: certain matrix types and will generate an error message if set.
5319: If using a Fortran 77 module to compute a matrix, one may need to
5320: use the column-oriented option (or convert to the row-oriented
5321: format).
5323: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5324: that would generate a new entry in the nonzero structure is instead
5325: ignored. Thus, if memory has not alredy been allocated for this particular
5326: data, then the insertion is ignored. For dense matrices, in which
5327: the entire array is allocated, no entries are ever ignored.
5328: Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5330: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5331: that would generate a new entry in the nonzero structure instead produces
5332: an error. (Currently supported for AIJ and BAIJ formats only.) If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5334: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5335: that would generate a new entry that has not been preallocated will
5336: instead produce an error. (Currently supported for AIJ and BAIJ formats
5337: only.) This is a useful flag when debugging matrix memory preallocation.
5338: If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5340: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5341: other processors should be dropped, rather than stashed.
5342: This is useful if you know that the "owning" processor is also
5343: always generating the correct matrix entries, so that PETSc need
5344: not transfer duplicate entries generated on another processor.
5346: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5347: searches during matrix assembly. When this flag is set, the hash table
5348: is created during the first Matrix Assembly. This hash table is
5349: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5350: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5351: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5352: supported by MATMPIBAIJ format only.
5354: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5355: are kept in the nonzero structure
5357: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5358: a zero location in the matrix
5360: MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5362: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5363: zero row routines and thus improves performance for very large process counts.
5365: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5366: part of the matrix (since they should match the upper triangular part).
5368: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5370: Level: intermediate
5372: Concepts: matrices^setting options
5374: .seealso: MatOption, Mat
5376: @*/
5377: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5378: {
5384: if (op > 0) {
5387: }
5389: 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);
5390: 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()");
5392: switch (op) {
5393: case MAT_NO_OFF_PROC_ENTRIES:
5394: mat->nooffprocentries = flg;
5395: return(0);
5396: break;
5397: case MAT_SUBSET_OFF_PROC_ENTRIES:
5398: mat->subsetoffprocentries = flg;
5399: return(0);
5400: case MAT_NO_OFF_PROC_ZERO_ROWS:
5401: mat->nooffproczerorows = flg;
5402: return(0);
5403: break;
5404: case MAT_SPD:
5405: mat->spd_set = PETSC_TRUE;
5406: mat->spd = flg;
5407: if (flg) {
5408: mat->symmetric = PETSC_TRUE;
5409: mat->structurally_symmetric = PETSC_TRUE;
5410: mat->symmetric_set = PETSC_TRUE;
5411: mat->structurally_symmetric_set = PETSC_TRUE;
5412: }
5413: break;
5414: case MAT_SYMMETRIC:
5415: mat->symmetric = flg;
5416: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5417: mat->symmetric_set = PETSC_TRUE;
5418: mat->structurally_symmetric_set = flg;
5419: #if !defined(PETSC_USE_COMPLEX)
5420: mat->hermitian = flg;
5421: mat->hermitian_set = PETSC_TRUE;
5422: #endif
5423: break;
5424: case MAT_HERMITIAN:
5425: mat->hermitian = flg;
5426: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5427: mat->hermitian_set = PETSC_TRUE;
5428: mat->structurally_symmetric_set = flg;
5429: #if !defined(PETSC_USE_COMPLEX)
5430: mat->symmetric = flg;
5431: mat->symmetric_set = PETSC_TRUE;
5432: #endif
5433: break;
5434: case MAT_STRUCTURALLY_SYMMETRIC:
5435: mat->structurally_symmetric = flg;
5436: mat->structurally_symmetric_set = PETSC_TRUE;
5437: break;
5438: case MAT_SYMMETRY_ETERNAL:
5439: mat->symmetric_eternal = flg;
5440: break;
5441: case MAT_STRUCTURE_ONLY:
5442: mat->structure_only = flg;
5443: break;
5444: default:
5445: break;
5446: }
5447: if (mat->ops->setoption) {
5448: (*mat->ops->setoption)(mat,op,flg);
5449: }
5450: return(0);
5451: }
5453: /*@
5454: MatGetOption - Gets a parameter option that has been set for a matrix.
5456: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5458: Input Parameters:
5459: + mat - the matrix
5460: - option - the option, this only responds to certain options, check the code for which ones
5462: Output Parameter:
5463: . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5465: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5467: Level: intermediate
5469: Concepts: matrices^setting options
5471: .seealso: MatOption, MatSetOption()
5473: @*/
5474: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5475: {
5480: 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);
5481: if (!((PetscObject)mat)->type_name) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_TYPENOTSET,"Cannot get options until type and size have been set, see MatSetType() and MatSetSizes()");
5483: switch (op) {
5484: case MAT_NO_OFF_PROC_ENTRIES:
5485: *flg = mat->nooffprocentries;
5486: break;
5487: case MAT_NO_OFF_PROC_ZERO_ROWS:
5488: *flg = mat->nooffproczerorows;
5489: break;
5490: case MAT_SYMMETRIC:
5491: *flg = mat->symmetric;
5492: break;
5493: case MAT_HERMITIAN:
5494: *flg = mat->hermitian;
5495: break;
5496: case MAT_STRUCTURALLY_SYMMETRIC:
5497: *flg = mat->structurally_symmetric;
5498: break;
5499: case MAT_SYMMETRY_ETERNAL:
5500: *flg = mat->symmetric_eternal;
5501: break;
5502: case MAT_SPD:
5503: *flg = mat->spd;
5504: break;
5505: default:
5506: break;
5507: }
5508: return(0);
5509: }
5511: /*@
5512: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5513: this routine retains the old nonzero structure.
5515: Logically Collective on Mat
5517: Input Parameters:
5518: . mat - the matrix
5520: Level: intermediate
5522: 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.
5523: See the Performance chapter of the users manual for information on preallocating matrices.
5525: Concepts: matrices^zeroing
5527: .seealso: MatZeroRows()
5528: @*/
5529: PetscErrorCode MatZeroEntries(Mat mat)
5530: {
5536: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5537: 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");
5538: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5539: MatCheckPreallocated(mat,1);
5541: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5542: (*mat->ops->zeroentries)(mat);
5543: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5544: PetscObjectStateIncrease((PetscObject)mat);
5545: #if defined(PETSC_HAVE_CUSP)
5546: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5547: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5548: }
5549: #elif defined(PETSC_HAVE_VIENNACL)
5550: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5551: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5552: }
5553: #elif defined(PETSC_HAVE_VECCUDA)
5554: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5555: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5556: }
5557: #endif
5558: return(0);
5559: }
5561: /*@C
5562: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5563: of a set of rows and columns of a matrix.
5565: Collective on Mat
5567: Input Parameters:
5568: + mat - the matrix
5569: . numRows - the number of rows to remove
5570: . rows - the global row indices
5571: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5572: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5573: - b - optional vector of right hand side, that will be adjusted by provided solution
5575: Notes:
5576: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5578: The user can set a value in the diagonal entry (or for the AIJ and
5579: row formats can optionally remove the main diagonal entry from the
5580: nonzero structure as well, by passing 0.0 as the final argument).
5582: For the parallel case, all processes that share the matrix (i.e.,
5583: those in the communicator used for matrix creation) MUST call this
5584: routine, regardless of whether any rows being zeroed are owned by
5585: them.
5587: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5588: list only rows local to itself).
5590: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5592: Level: intermediate
5594: Concepts: matrices^zeroing rows
5596: .seealso: MatZeroRowsIS(), MatZeroRows(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5597: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5598: @*/
5599: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5600: {
5607: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5608: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5609: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5610: MatCheckPreallocated(mat,1);
5612: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5613: MatViewFromOptions(mat,NULL,"-mat_view");
5614: PetscObjectStateIncrease((PetscObject)mat);
5615: #if defined(PETSC_HAVE_CUSP)
5616: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5617: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5618: }
5619: #elif defined(PETSC_HAVE_VIENNACL)
5620: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5621: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5622: }
5623: #elif defined(PETSC_HAVE_VECCUDA)
5624: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5625: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5626: }
5627: #endif
5628: return(0);
5629: }
5631: /*@C
5632: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5633: of a set of rows and columns of a matrix.
5635: Collective on Mat
5637: Input Parameters:
5638: + mat - the matrix
5639: . is - the rows to zero
5640: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5641: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5642: - b - optional vector of right hand side, that will be adjusted by provided solution
5644: Notes:
5645: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5647: The user can set a value in the diagonal entry (or for the AIJ and
5648: row formats can optionally remove the main diagonal entry from the
5649: nonzero structure as well, by passing 0.0 as the final argument).
5651: For the parallel case, all processes that share the matrix (i.e.,
5652: those in the communicator used for matrix creation) MUST call this
5653: routine, regardless of whether any rows being zeroed are owned by
5654: them.
5656: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5657: list only rows local to itself).
5659: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5661: Level: intermediate
5663: Concepts: matrices^zeroing rows
5665: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5666: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRows(), MatZeroRowsColumnsStencil()
5667: @*/
5668: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5669: {
5671: PetscInt numRows;
5672: const PetscInt *rows;
5679: ISGetLocalSize(is,&numRows);
5680: ISGetIndices(is,&rows);
5681: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5682: ISRestoreIndices(is,&rows);
5683: return(0);
5684: }
5686: /*@C
5687: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5688: of a set of rows of a matrix.
5690: Collective on Mat
5692: Input Parameters:
5693: + mat - the matrix
5694: . numRows - the number of rows to remove
5695: . rows - the global row indices
5696: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5697: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5698: - b - optional vector of right hand side, that will be adjusted by provided solution
5700: Notes:
5701: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5702: but does not release memory. For the dense and block diagonal
5703: formats this does not alter the nonzero structure.
5705: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5706: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5707: merely zeroed.
5709: The user can set a value in the diagonal entry (or for the AIJ and
5710: row formats can optionally remove the main diagonal entry from the
5711: nonzero structure as well, by passing 0.0 as the final argument).
5713: For the parallel case, all processes that share the matrix (i.e.,
5714: those in the communicator used for matrix creation) MUST call this
5715: routine, regardless of whether any rows being zeroed are owned by
5716: them.
5718: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5719: list only rows local to itself).
5721: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5722: owns that are to be zeroed. This saves a global synchronization in the implementation.
5724: Level: intermediate
5726: Concepts: matrices^zeroing rows
5728: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5729: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5730: @*/
5731: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5732: {
5739: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5740: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5741: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5742: MatCheckPreallocated(mat,1);
5744: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5745: MatViewFromOptions(mat,NULL,"-mat_view");
5746: PetscObjectStateIncrease((PetscObject)mat);
5747: #if defined(PETSC_HAVE_CUSP)
5748: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5749: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5750: }
5751: #elif defined(PETSC_HAVE_VIENNACL)
5752: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5753: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5754: }
5755: #elif defined(PETSC_HAVE_VECCUDA)
5756: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5757: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5758: }
5759: #endif
5760: return(0);
5761: }
5763: /*@C
5764: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5765: of a set of rows of a matrix.
5767: Collective on Mat
5769: Input Parameters:
5770: + mat - the matrix
5771: . is - index set of rows to remove
5772: . diag - value put in all diagonals of eliminated rows
5773: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5774: - b - optional vector of right hand side, that will be adjusted by provided solution
5776: Notes:
5777: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5778: but does not release memory. For the dense and block diagonal
5779: formats this does not alter the nonzero structure.
5781: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5782: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5783: merely zeroed.
5785: The user can set a value in the diagonal entry (or for the AIJ and
5786: row formats can optionally remove the main diagonal entry from the
5787: nonzero structure as well, by passing 0.0 as the final argument).
5789: For the parallel case, all processes that share the matrix (i.e.,
5790: those in the communicator used for matrix creation) MUST call this
5791: routine, regardless of whether any rows being zeroed are owned by
5792: them.
5794: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5795: list only rows local to itself).
5797: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5798: owns that are to be zeroed. This saves a global synchronization in the implementation.
5800: Level: intermediate
5802: Concepts: matrices^zeroing rows
5804: .seealso: MatZeroRows(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5805: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5806: @*/
5807: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5808: {
5809: PetscInt numRows;
5810: const PetscInt *rows;
5817: ISGetLocalSize(is,&numRows);
5818: ISGetIndices(is,&rows);
5819: MatZeroRows(mat,numRows,rows,diag,x,b);
5820: ISRestoreIndices(is,&rows);
5821: return(0);
5822: }
5824: /*@C
5825: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5826: of a set of rows of a matrix. These rows must be local to the process.
5828: Collective on Mat
5830: Input Parameters:
5831: + mat - the matrix
5832: . numRows - the number of rows to remove
5833: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5834: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5835: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5836: - b - optional vector of right hand side, that will be adjusted by provided solution
5838: Notes:
5839: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5840: but does not release memory. For the dense and block diagonal
5841: formats this does not alter the nonzero structure.
5843: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5844: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5845: merely zeroed.
5847: The user can set a value in the diagonal entry (or for the AIJ and
5848: row formats can optionally remove the main diagonal entry from the
5849: nonzero structure as well, by passing 0.0 as the final argument).
5851: For the parallel case, all processes that share the matrix (i.e.,
5852: those in the communicator used for matrix creation) MUST call this
5853: routine, regardless of whether any rows being zeroed are owned by
5854: them.
5856: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5857: list only rows local to itself).
5859: The grid coordinates are across the entire grid, not just the local portion
5861: In Fortran idxm and idxn should be declared as
5862: $ MatStencil idxm(4,m)
5863: and the values inserted using
5864: $ idxm(MatStencil_i,1) = i
5865: $ idxm(MatStencil_j,1) = j
5866: $ idxm(MatStencil_k,1) = k
5867: $ idxm(MatStencil_c,1) = c
5868: etc
5870: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5871: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5872: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5873: DM_BOUNDARY_PERIODIC boundary type.
5875: 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
5876: a single value per point) you can skip filling those indices.
5878: Level: intermediate
5880: Concepts: matrices^zeroing rows
5882: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsl(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5883: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
5884: @*/
5885: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5886: {
5887: PetscInt dim = mat->stencil.dim;
5888: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5889: PetscInt *dims = mat->stencil.dims+1;
5890: PetscInt *starts = mat->stencil.starts;
5891: PetscInt *dxm = (PetscInt*) rows;
5892: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5900: PetscMalloc1(numRows, &jdxm);
5901: for (i = 0; i < numRows; ++i) {
5902: /* Skip unused dimensions (they are ordered k, j, i, c) */
5903: for (j = 0; j < 3-sdim; ++j) dxm++;
5904: /* Local index in X dir */
5905: tmp = *dxm++ - starts[0];
5906: /* Loop over remaining dimensions */
5907: for (j = 0; j < dim-1; ++j) {
5908: /* If nonlocal, set index to be negative */
5909: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5910: /* Update local index */
5911: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5912: }
5913: /* Skip component slot if necessary */
5914: if (mat->stencil.noc) dxm++;
5915: /* Local row number */
5916: if (tmp >= 0) {
5917: jdxm[numNewRows++] = tmp;
5918: }
5919: }
5920: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5921: PetscFree(jdxm);
5922: return(0);
5923: }
5925: /*@C
5926: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5927: of a set of rows and columns of a matrix.
5929: Collective on Mat
5931: Input Parameters:
5932: + mat - the matrix
5933: . numRows - the number of rows/columns to remove
5934: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5935: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5936: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5937: - b - optional vector of right hand side, that will be adjusted by provided solution
5939: Notes:
5940: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5941: but does not release memory. For the dense and block diagonal
5942: formats this does not alter the nonzero structure.
5944: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5945: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5946: merely zeroed.
5948: The user can set a value in the diagonal entry (or for the AIJ and
5949: row formats can optionally remove the main diagonal entry from the
5950: nonzero structure as well, by passing 0.0 as the final argument).
5952: For the parallel case, all processes that share the matrix (i.e.,
5953: those in the communicator used for matrix creation) MUST call this
5954: routine, regardless of whether any rows being zeroed are owned by
5955: them.
5957: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5958: list only rows local to itself, but the row/column numbers are given in local numbering).
5960: The grid coordinates are across the entire grid, not just the local portion
5962: In Fortran idxm and idxn should be declared as
5963: $ MatStencil idxm(4,m)
5964: and the values inserted using
5965: $ idxm(MatStencil_i,1) = i
5966: $ idxm(MatStencil_j,1) = j
5967: $ idxm(MatStencil_k,1) = k
5968: $ idxm(MatStencil_c,1) = c
5969: etc
5971: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5972: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5973: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5974: DM_BOUNDARY_PERIODIC boundary type.
5976: 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
5977: a single value per point) you can skip filling those indices.
5979: Level: intermediate
5981: Concepts: matrices^zeroing rows
5983: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
5984: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRows()
5985: @*/
5986: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5987: {
5988: PetscInt dim = mat->stencil.dim;
5989: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5990: PetscInt *dims = mat->stencil.dims+1;
5991: PetscInt *starts = mat->stencil.starts;
5992: PetscInt *dxm = (PetscInt*) rows;
5993: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
6001: PetscMalloc1(numRows, &jdxm);
6002: for (i = 0; i < numRows; ++i) {
6003: /* Skip unused dimensions (they are ordered k, j, i, c) */
6004: for (j = 0; j < 3-sdim; ++j) dxm++;
6005: /* Local index in X dir */
6006: tmp = *dxm++ - starts[0];
6007: /* Loop over remaining dimensions */
6008: for (j = 0; j < dim-1; ++j) {
6009: /* If nonlocal, set index to be negative */
6010: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
6011: /* Update local index */
6012: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
6013: }
6014: /* Skip component slot if necessary */
6015: if (mat->stencil.noc) dxm++;
6016: /* Local row number */
6017: if (tmp >= 0) {
6018: jdxm[numNewRows++] = tmp;
6019: }
6020: }
6021: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6022: PetscFree(jdxm);
6023: return(0);
6024: }
6026: /*@C
6027: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6028: of a set of rows of a matrix; using local numbering of rows.
6030: Collective on Mat
6032: Input Parameters:
6033: + mat - the matrix
6034: . numRows - the number of rows to remove
6035: . rows - the global row indices
6036: . diag - value put in all diagonals of eliminated rows
6037: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6038: - b - optional vector of right hand side, that will be adjusted by provided solution
6040: Notes:
6041: Before calling MatZeroRowsLocal(), the user must first set the
6042: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6044: For the AIJ matrix formats this removes the old nonzero structure,
6045: but does not release memory. For the dense and block diagonal
6046: formats this does not alter the nonzero structure.
6048: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6049: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6050: merely zeroed.
6052: The user can set a value in the diagonal entry (or for the AIJ and
6053: row formats can optionally remove the main diagonal entry from the
6054: nonzero structure as well, by passing 0.0 as the final argument).
6056: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6057: owns that are to be zeroed. This saves a global synchronization in the implementation.
6059: Level: intermediate
6061: Concepts: matrices^zeroing
6063: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRows(), MatSetOption(),
6064: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6065: @*/
6066: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6067: {
6074: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6075: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6076: MatCheckPreallocated(mat,1);
6078: if (mat->ops->zerorowslocal) {
6079: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6080: } else {
6081: IS is, newis;
6082: const PetscInt *newRows;
6084: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6085: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6086: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6087: ISGetIndices(newis,&newRows);
6088: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6089: ISRestoreIndices(newis,&newRows);
6090: ISDestroy(&newis);
6091: ISDestroy(&is);
6092: }
6093: PetscObjectStateIncrease((PetscObject)mat);
6094: #if defined(PETSC_HAVE_CUSP)
6095: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6096: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6097: }
6098: #elif defined(PETSC_HAVE_VIENNACL)
6099: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6100: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6101: }
6102: #elif defined(PETSC_HAVE_VECCUDA)
6103: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6104: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6105: }
6106: #endif
6107: return(0);
6108: }
6110: /*@C
6111: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6112: of a set of rows of a matrix; using local numbering of rows.
6114: Collective on Mat
6116: Input Parameters:
6117: + mat - the matrix
6118: . is - index set of rows to remove
6119: . diag - value put in all diagonals of eliminated rows
6120: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6121: - b - optional vector of right hand side, that will be adjusted by provided solution
6123: Notes:
6124: Before calling MatZeroRowsLocalIS(), the user must first set the
6125: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6127: For the AIJ matrix formats this removes the old nonzero structure,
6128: but does not release memory. For the dense and block diagonal
6129: formats this does not alter the nonzero structure.
6131: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6132: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6133: merely zeroed.
6135: The user can set a value in the diagonal entry (or for the AIJ and
6136: row formats can optionally remove the main diagonal entry from the
6137: nonzero structure as well, by passing 0.0 as the final argument).
6139: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6140: owns that are to be zeroed. This saves a global synchronization in the implementation.
6142: Level: intermediate
6144: Concepts: matrices^zeroing
6146: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6147: MatZeroRowsColumnsLocal(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6148: @*/
6149: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6150: {
6152: PetscInt numRows;
6153: const PetscInt *rows;
6159: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6160: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6161: MatCheckPreallocated(mat,1);
6163: ISGetLocalSize(is,&numRows);
6164: ISGetIndices(is,&rows);
6165: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6166: ISRestoreIndices(is,&rows);
6167: return(0);
6168: }
6170: /*@C
6171: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6172: of a set of rows and columns of a matrix; using local numbering of rows.
6174: Collective on Mat
6176: Input Parameters:
6177: + mat - the matrix
6178: . numRows - the number of rows to remove
6179: . rows - the global row indices
6180: . diag - value put in all diagonals of eliminated rows
6181: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6182: - b - optional vector of right hand side, that will be adjusted by provided solution
6184: Notes:
6185: Before calling MatZeroRowsColumnsLocal(), the user must first set the
6186: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6188: The user can set a value in the diagonal entry (or for the AIJ and
6189: row formats can optionally remove the main diagonal entry from the
6190: nonzero structure as well, by passing 0.0 as the final argument).
6192: Level: intermediate
6194: Concepts: matrices^zeroing
6196: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6197: MatZeroRows(), MatZeroRowsColumnsLocalIS(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6198: @*/
6199: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6200: {
6202: IS is, newis;
6203: const PetscInt *newRows;
6209: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6210: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6211: MatCheckPreallocated(mat,1);
6213: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6214: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6215: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6216: ISGetIndices(newis,&newRows);
6217: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6218: ISRestoreIndices(newis,&newRows);
6219: ISDestroy(&newis);
6220: ISDestroy(&is);
6221: PetscObjectStateIncrease((PetscObject)mat);
6222: #if defined(PETSC_HAVE_CUSP)
6223: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6224: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6225: }
6226: #elif defined(PETSC_HAVE_VIENNACL)
6227: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6228: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6229: }
6230: #elif defined(PETSC_HAVE_VECCUDA)
6231: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6232: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6233: }
6234: #endif
6235: return(0);
6236: }
6238: /*@C
6239: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6240: of a set of rows and columns of a matrix; using local numbering of rows.
6242: Collective on Mat
6244: Input Parameters:
6245: + mat - the matrix
6246: . is - index set of rows to remove
6247: . diag - value put in all diagonals of eliminated rows
6248: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6249: - b - optional vector of right hand side, that will be adjusted by provided solution
6251: Notes:
6252: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6253: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6255: The user can set a value in the diagonal entry (or for the AIJ and
6256: row formats can optionally remove the main diagonal entry from the
6257: nonzero structure as well, by passing 0.0 as the final argument).
6259: Level: intermediate
6261: Concepts: matrices^zeroing
6263: .seealso: MatZeroRowsIS(), MatZeroRowsColumns(), MatZeroRowsLocalIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(),
6264: MatZeroRowsColumnsLocal(), MatZeroRows(), MatZeroRowsColumnsIS(), MatZeroRowsColumnsStencil()
6265: @*/
6266: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6267: {
6269: PetscInt numRows;
6270: const PetscInt *rows;
6276: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6277: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6278: MatCheckPreallocated(mat,1);
6280: ISGetLocalSize(is,&numRows);
6281: ISGetIndices(is,&rows);
6282: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6283: ISRestoreIndices(is,&rows);
6284: return(0);
6285: }
6287: /*@C
6288: MatGetSize - Returns the numbers of rows and columns in a matrix.
6290: Not Collective
6292: Input Parameter:
6293: . mat - the matrix
6295: Output Parameters:
6296: + m - the number of global rows
6297: - n - the number of global columns
6299: Note: both output parameters can be NULL on input.
6301: Level: beginner
6303: Concepts: matrices^size
6305: .seealso: MatGetLocalSize()
6306: @*/
6307: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6308: {
6311: if (m) *m = mat->rmap->N;
6312: if (n) *n = mat->cmap->N;
6313: return(0);
6314: }
6316: /*@C
6317: MatGetLocalSize - Returns the number of rows and columns in a matrix
6318: stored locally. This information may be implementation dependent, so
6319: use with care.
6321: Not Collective
6323: Input Parameters:
6324: . mat - the matrix
6326: Output Parameters:
6327: + m - the number of local rows
6328: - n - the number of local columns
6330: Note: both output parameters can be NULL on input.
6332: Level: beginner
6334: Concepts: matrices^local size
6336: .seealso: MatGetSize()
6337: @*/
6338: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6339: {
6344: if (m) *m = mat->rmap->n;
6345: if (n) *n = mat->cmap->n;
6346: return(0);
6347: }
6349: /*@
6350: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6351: this processor. (The columns of the "diagonal block")
6353: Not Collective, unless matrix has not been allocated, then collective on Mat
6355: Input Parameters:
6356: . mat - the matrix
6358: Output Parameters:
6359: + m - the global index of the first local column
6360: - n - one more than the global index of the last local column
6362: Notes: both output parameters can be NULL on input.
6364: Level: developer
6366: Concepts: matrices^column ownership
6368: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6370: @*/
6371: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6372: {
6378: MatCheckPreallocated(mat,1);
6379: if (m) *m = mat->cmap->rstart;
6380: if (n) *n = mat->cmap->rend;
6381: return(0);
6382: }
6384: /*@
6385: MatGetOwnershipRange - Returns the range of matrix rows owned by
6386: this processor, assuming that the matrix is laid out with the first
6387: n1 rows on the first processor, the next n2 rows on the second, etc.
6388: For certain parallel layouts this range may not be well defined.
6390: Not Collective
6392: Input Parameters:
6393: . mat - the matrix
6395: Output Parameters:
6396: + m - the global index of the first local row
6397: - n - one more than the global index of the last local row
6399: Note: Both output parameters can be NULL on input.
6400: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6401: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6402: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6404: Level: beginner
6406: Concepts: matrices^row ownership
6408: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6410: @*/
6411: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6412: {
6418: MatCheckPreallocated(mat,1);
6419: if (m) *m = mat->rmap->rstart;
6420: if (n) *n = mat->rmap->rend;
6421: return(0);
6422: }
6424: /*@C
6425: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6426: each process
6428: Not Collective, unless matrix has not been allocated, then collective on Mat
6430: Input Parameters:
6431: . mat - the matrix
6433: Output Parameters:
6434: . ranges - start of each processors portion plus one more than the total length at the end
6436: Level: beginner
6438: Concepts: matrices^row ownership
6440: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6442: @*/
6443: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6444: {
6450: MatCheckPreallocated(mat,1);
6451: PetscLayoutGetRanges(mat->rmap,ranges);
6452: return(0);
6453: }
6455: /*@C
6456: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6457: this processor. (The columns of the "diagonal blocks" for each process)
6459: Not Collective, unless matrix has not been allocated, then collective on Mat
6461: Input Parameters:
6462: . mat - the matrix
6464: Output Parameters:
6465: . ranges - start of each processors portion plus one more then the total length at the end
6467: Level: beginner
6469: Concepts: matrices^column ownership
6471: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6473: @*/
6474: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6475: {
6481: MatCheckPreallocated(mat,1);
6482: PetscLayoutGetRanges(mat->cmap,ranges);
6483: return(0);
6484: }
6486: /*@C
6487: MatGetOwnershipIS - Get row and column ownership as index sets
6489: Not Collective
6491: Input Arguments:
6492: . A - matrix of type Elemental
6494: Output Arguments:
6495: + rows - rows in which this process owns elements
6496: . cols - columns in which this process owns elements
6498: Level: intermediate
6500: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6501: @*/
6502: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6503: {
6504: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6507: MatCheckPreallocated(A,1);
6508: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6509: if (f) {
6510: (*f)(A,rows,cols);
6511: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6512: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6513: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6514: }
6515: return(0);
6516: }
6518: /*@C
6519: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6520: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6521: to complete the factorization.
6523: Collective on Mat
6525: Input Parameters:
6526: + mat - the matrix
6527: . row - row permutation
6528: . column - column permutation
6529: - info - structure containing
6530: $ levels - number of levels of fill.
6531: $ expected fill - as ratio of original fill.
6532: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6533: missing diagonal entries)
6535: Output Parameters:
6536: . fact - new matrix that has been symbolically factored
6538: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6540: Most users should employ the simplified KSP interface for linear solvers
6541: instead of working directly with matrix algebra routines such as this.
6542: See, e.g., KSPCreate().
6544: Level: developer
6546: Concepts: matrices^symbolic LU factorization
6547: Concepts: matrices^factorization
6548: Concepts: LU^symbolic factorization
6550: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6551: MatGetOrdering(), MatFactorInfo
6553: Developer Note: fortran interface is not autogenerated as the f90
6554: interface defintion cannot be generated correctly [due to MatFactorInfo]
6556: @*/
6557: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6558: {
6568: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6569: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6570: if (!(fact)->ops->ilufactorsymbolic) {
6571: const MatSolverPackage spackage;
6572: MatFactorGetSolverPackage(fact,&spackage);
6573: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6574: }
6575: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6576: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6577: MatCheckPreallocated(mat,2);
6579: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6580: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6581: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6582: return(0);
6583: }
6585: /*@C
6586: MatICCFactorSymbolic - Performs symbolic incomplete
6587: Cholesky factorization for a symmetric matrix. Use
6588: MatCholeskyFactorNumeric() to complete the factorization.
6590: Collective on Mat
6592: Input Parameters:
6593: + mat - the matrix
6594: . perm - row and column permutation
6595: - info - structure containing
6596: $ levels - number of levels of fill.
6597: $ expected fill - as ratio of original fill.
6599: Output Parameter:
6600: . fact - the factored matrix
6602: Notes:
6603: Most users should employ the KSP interface for linear solvers
6604: instead of working directly with matrix algebra routines such as this.
6605: See, e.g., KSPCreate().
6607: Level: developer
6609: Concepts: matrices^symbolic incomplete Cholesky factorization
6610: Concepts: matrices^factorization
6611: Concepts: Cholsky^symbolic factorization
6613: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6615: Developer Note: fortran interface is not autogenerated as the f90
6616: interface defintion cannot be generated correctly [due to MatFactorInfo]
6618: @*/
6619: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6620: {
6629: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6630: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6631: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6632: if (!(fact)->ops->iccfactorsymbolic) {
6633: const MatSolverPackage spackage;
6634: MatFactorGetSolverPackage(fact,&spackage);
6635: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6636: }
6637: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6638: MatCheckPreallocated(mat,2);
6640: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6641: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6642: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6643: return(0);
6644: }
6646: /*@C
6647: MatCreateSubMatrices - Extracts several submatrices from a matrix. If submat
6648: points to an array of valid matrices, they may be reused to store the new
6649: submatrices.
6651: Collective on Mat
6653: Input Parameters:
6654: + mat - the matrix
6655: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6656: . irow, icol - index sets of rows and columns to extract
6657: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6659: Output Parameter:
6660: . submat - the array of submatrices
6662: Notes:
6663: MatCreateSubMatrices() can extract ONLY sequential submatrices
6664: (from both sequential and parallel matrices). Use MatCreateSubMatrix()
6665: to extract a parallel submatrix.
6667: Some matrix types place restrictions on the row and column
6668: indices, such as that they be sorted or that they be equal to each other.
6670: The index sets may not have duplicate entries.
6672: When extracting submatrices from a parallel matrix, each processor can
6673: form a different submatrix by setting the rows and columns of its
6674: individual index sets according to the local submatrix desired.
6676: When finished using the submatrices, the user should destroy
6677: them with MatDestroyMatrices().
6679: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6680: original matrix has not changed from that last call to MatCreateSubMatrices().
6682: This routine creates the matrices in submat; you should NOT create them before
6683: calling it. It also allocates the array of matrix pointers submat.
6685: For BAIJ matrices the index sets must respect the block structure, that is if they
6686: request one row/column in a block, they must request all rows/columns that are in
6687: that block. For example, if the block size is 2 you cannot request just row 0 and
6688: column 0.
6690: Fortran Note:
6691: The Fortran interface is slightly different from that given below; it
6692: requires one to pass in as submat a Mat (integer) array of size at least m.
6694: Level: advanced
6696: Concepts: matrices^accessing submatrices
6697: Concepts: submatrices
6699: .seealso: MatDestroySubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6700: @*/
6701: PetscErrorCode MatCreateSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6702: {
6704: PetscInt i;
6705: PetscBool eq;
6710: if (n) {
6715: }
6717: if (n && scall == MAT_REUSE_MATRIX) {
6720: }
6721: if (!mat->ops->createsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6722: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6723: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6724: MatCheckPreallocated(mat,1);
6726: PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6727: (*mat->ops->createsubmatrices)(mat,n,irow,icol,scall,submat);
6728: PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6729: for (i=0; i<n; i++) {
6730: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6731: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6732: ISEqual(irow[i],icol[i],&eq);
6733: if (eq) {
6734: if (mat->symmetric) {
6735: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6736: } else if (mat->hermitian) {
6737: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6738: } else if (mat->structurally_symmetric) {
6739: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6740: }
6741: }
6742: }
6743: }
6744: return(0);
6745: }
6747: /*@C
6748: MatCreateSubMatricesMPI - Extracts MPI submatrices across a sub communicator of mat (by pairs of IS that may live on subcomms).
6750: Collective on Mat
6752: Input Parameters:
6753: + mat - the matrix
6754: . n - the number of submatrixes to be extracted
6755: . irow, icol - index sets of rows and columns to extract
6756: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6758: Output Parameter:
6759: . submat - the array of submatrices
6761: Level: advanced
6763: Concepts: matrices^accessing submatrices
6764: Concepts: submatrices
6766: .seealso: MatCreateSubMatrices(), MatCreateSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6767: @*/
6768: PetscErrorCode MatCreateSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6769: {
6771: PetscInt i;
6772: PetscBool eq;
6777: if (n) {
6782: }
6784: if (n && scall == MAT_REUSE_MATRIX) {
6787: }
6788: if (!mat->ops->createsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6789: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6790: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6791: MatCheckPreallocated(mat,1);
6793: PetscLogEventBegin(MAT_CreateSubMats,mat,0,0,0);
6794: (*mat->ops->createsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6795: PetscLogEventEnd(MAT_CreateSubMats,mat,0,0,0);
6796: for (i=0; i<n; i++) {
6797: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6798: ISEqual(irow[i],icol[i],&eq);
6799: if (eq) {
6800: if (mat->symmetric) {
6801: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6802: } else if (mat->hermitian) {
6803: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6804: } else if (mat->structurally_symmetric) {
6805: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6806: }
6807: }
6808: }
6809: }
6810: return(0);
6811: }
6813: /*@C
6814: MatDestroyMatrices - Destroys an array of matrices.
6816: Collective on Mat
6818: Input Parameters:
6819: + n - the number of local matrices
6820: - mat - the matrices (note that this is a pointer to the array of matrices)
6822: Level: advanced
6824: Notes: Frees not only the matrices, but also the array that contains the matrices
6825: In Fortran will not free the array.
6827: .seealso: MatCreateSubMatrices() MatDestroySubMatrices()
6828: @*/
6829: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6830: {
6832: PetscInt i;
6835: if (!*mat) return(0);
6836: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6839: for (i=0; i<n; i++) {
6840: MatDestroy(&(*mat)[i]);
6841: }
6843: /* memory is allocated even if n = 0 */
6844: PetscFree(*mat);
6845: return(0);
6846: }
6848: /*@C
6849: MatDestroySubMatrices - Destroys a set of matrices obtained with MatCreateSubMatrices().
6851: Collective on Mat
6853: Input Parameters:
6854: + n - the number of local matrices
6855: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6856: sequence of MatCreateSubMatrices())
6858: Level: advanced
6860: Notes: Frees not only the matrices, but also the array that contains the matrices
6861: In Fortran will not free the array.
6863: .seealso: MatCreateSubMatrices()
6864: @*/
6865: PetscErrorCode MatDestroySubMatrices(PetscInt n,Mat *mat[])
6866: {
6868: Mat mat0;
6871: if (!*mat) return(0);
6872: /* mat[] is an array of length n+1, see MatCreateSubMatrices_xxx() */
6873: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6876: mat0 = (*mat)[0];
6877: if (mat0 && mat0->ops->destroysubmatrices) {
6878: (mat0->ops->destroysubmatrices)(n,mat);
6879: } else {
6880: MatDestroyMatrices(n,mat);
6881: }
6882: return(0);
6883: }
6885: /*@C
6886: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6888: Collective on Mat
6890: Input Parameters:
6891: . mat - the matrix
6893: Output Parameter:
6894: . matstruct - the sequential matrix with the nonzero structure of mat
6896: Level: intermediate
6898: .seealso: MatDestroySeqNonzeroStructure(), MatCreateSubMatrices(), MatDestroyMatrices()
6899: @*/
6900: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6901: {
6909: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6910: MatCheckPreallocated(mat,1);
6912: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6913: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6914: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6915: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6916: return(0);
6917: }
6919: /*@C
6920: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6922: Collective on Mat
6924: Input Parameters:
6925: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6926: sequence of MatGetSequentialNonzeroStructure())
6928: Level: advanced
6930: Notes: Frees not only the matrices, but also the array that contains the matrices
6932: .seealso: MatGetSeqNonzeroStructure()
6933: @*/
6934: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6935: {
6940: MatDestroy(mat);
6941: return(0);
6942: }
6944: /*@
6945: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6946: replaces the index sets by larger ones that represent submatrices with
6947: additional overlap.
6949: Collective on Mat
6951: Input Parameters:
6952: + mat - the matrix
6953: . n - the number of index sets
6954: . is - the array of index sets (these index sets will changed during the call)
6955: - ov - the additional overlap requested
6957: Options Database:
6958: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6960: Level: developer
6962: Concepts: overlap
6963: Concepts: ASM^computing overlap
6965: .seealso: MatCreateSubMatrices()
6966: @*/
6967: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6968: {
6974: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6975: if (n) {
6978: }
6979: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6980: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6981: MatCheckPreallocated(mat,1);
6983: if (!ov) return(0);
6984: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6985: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6986: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6987: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6988: return(0);
6989: }
6992: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6994: /*@
6995: MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6996: a sub communicator, replaces the index sets by larger ones that represent submatrices with
6997: additional overlap.
6999: Collective on Mat
7001: Input Parameters:
7002: + mat - the matrix
7003: . n - the number of index sets
7004: . is - the array of index sets (these index sets will changed during the call)
7005: - ov - the additional overlap requested
7007: Options Database:
7008: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
7010: Level: developer
7012: Concepts: overlap
7013: Concepts: ASM^computing overlap
7015: .seealso: MatCreateSubMatrices()
7016: @*/
7017: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
7018: {
7019: PetscInt i;
7025: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
7026: if (n) {
7029: }
7030: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
7031: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7032: MatCheckPreallocated(mat,1);
7033: if (!ov) return(0);
7034: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
7035: for(i=0; i<n; i++){
7036: MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
7037: }
7038: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
7039: return(0);
7040: }
7045: /*@
7046: MatGetBlockSize - Returns the matrix block size.
7048: Not Collective
7050: Input Parameter:
7051: . mat - the matrix
7053: Output Parameter:
7054: . bs - block size
7056: Notes:
7057: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7059: If the block size has not been set yet this routine returns 1.
7061: Level: intermediate
7063: Concepts: matrices^block size
7065: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7066: @*/
7067: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7068: {
7072: *bs = PetscAbs(mat->rmap->bs);
7073: return(0);
7074: }
7076: /*@
7077: MatGetBlockSizes - Returns the matrix block row and column sizes.
7079: Not Collective
7081: Input Parameter:
7082: . mat - the matrix
7084: Output Parameter:
7085: . rbs - row block size
7086: . cbs - column block size
7088: Notes:
7089: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7090: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7092: If a block size has not been set yet this routine returns 1.
7094: Level: intermediate
7096: Concepts: matrices^block size
7098: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7099: @*/
7100: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7101: {
7106: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7107: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7108: return(0);
7109: }
7111: /*@
7112: MatSetBlockSize - Sets the matrix block size.
7114: Logically Collective on Mat
7116: Input Parameters:
7117: + mat - the matrix
7118: - bs - block size
7120: Notes:
7121: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7122: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later.
7124: For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block size
7125: is compatible with the matrix local sizes.
7127: Level: intermediate
7129: Concepts: matrices^block size
7131: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7132: @*/
7133: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7134: {
7140: MatSetBlockSizes(mat,bs,bs);
7141: return(0);
7142: }
7144: /*@
7145: MatSetBlockSizes - Sets the matrix block row and column sizes.
7147: Logically Collective on Mat
7149: Input Parameters:
7150: + mat - the matrix
7151: - rbs - row block size
7152: - cbs - column block size
7154: Notes:
7155: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7156: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7157: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7159: For MATMPIAIJ and MATSEQAIJ matrix formats, this function can be called at a later stage, provided that the specified block sizes
7160: are compatible with the matrix local sizes.
7162: The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7164: Level: intermediate
7166: Concepts: matrices^block size
7168: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7169: @*/
7170: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7171: {
7178: if (mat->ops->setblocksizes) {
7179: (*mat->ops->setblocksizes)(mat,rbs,cbs);
7180: }
7181: if (mat->rmap->refcnt) {
7182: ISLocalToGlobalMapping l2g = NULL;
7183: PetscLayout nmap = NULL;
7185: PetscLayoutDuplicate(mat->rmap,&nmap);
7186: if (mat->rmap->mapping) {
7187: ISLocalToGlobalMappingDuplicate(mat->rmap->mapping,&l2g);
7188: }
7189: PetscLayoutDestroy(&mat->rmap);
7190: mat->rmap = nmap;
7191: mat->rmap->mapping = l2g;
7192: }
7193: if (mat->cmap->refcnt) {
7194: ISLocalToGlobalMapping l2g = NULL;
7195: PetscLayout nmap = NULL;
7197: PetscLayoutDuplicate(mat->cmap,&nmap);
7198: if (mat->cmap->mapping) {
7199: ISLocalToGlobalMappingDuplicate(mat->cmap->mapping,&l2g);
7200: }
7201: PetscLayoutDestroy(&mat->cmap);
7202: mat->cmap = nmap;
7203: mat->cmap->mapping = l2g;
7204: }
7205: PetscLayoutSetBlockSize(mat->rmap,rbs);
7206: PetscLayoutSetBlockSize(mat->cmap,cbs);
7207: return(0);
7208: }
7210: /*@
7211: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7213: Logically Collective on Mat
7215: Input Parameters:
7216: + mat - the matrix
7217: . fromRow - matrix from which to copy row block size
7218: - fromCol - matrix from which to copy column block size (can be same as fromRow)
7220: Level: developer
7222: Concepts: matrices^block size
7224: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7225: @*/
7226: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7227: {
7234: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7235: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7236: return(0);
7237: }
7239: /*@
7240: MatResidual - Default routine to calculate the residual.
7242: Collective on Mat and Vec
7244: Input Parameters:
7245: + mat - the matrix
7246: . b - the right-hand-side
7247: - x - the approximate solution
7249: Output Parameter:
7250: . r - location to store the residual
7252: Level: developer
7254: .keywords: MG, default, multigrid, residual
7256: .seealso: PCMGSetResidual()
7257: @*/
7258: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7259: {
7268: MatCheckPreallocated(mat,1);
7269: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7270: if (!mat->ops->residual) {
7271: MatMult(mat,x,r);
7272: VecAYPX(r,-1.0,b);
7273: } else {
7274: (*mat->ops->residual)(mat,b,x,r);
7275: }
7276: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7277: return(0);
7278: }
7280: /*@C
7281: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7283: Collective on Mat
7285: Input Parameters:
7286: + mat - the matrix
7287: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7288: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7289: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7290: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7291: always used.
7293: Output Parameters:
7294: + n - number of rows in the (possibly compressed) matrix
7295: . ia - the row pointers [of length n+1]
7296: . ja - the column indices
7297: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7298: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7300: Level: developer
7302: Notes: You CANNOT change any of the ia[] or ja[] values.
7304: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7306: Fortran Node
7308: In Fortran use
7309: $ PetscInt ia(1), ja(1)
7310: $ PetscOffset iia, jja
7311: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7312: $ Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7313: $
7314: $ or
7315: $
7316: $ PetscInt, pointer :: ia(:),ja(:)
7317: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7318: $ Acess the ith and jth entries via ia(i) and ja(j)
7322: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7323: @*/
7324: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7325: {
7335: MatCheckPreallocated(mat,1);
7336: if (!mat->ops->getrowij) *done = PETSC_FALSE;
7337: else {
7338: *done = PETSC_TRUE;
7339: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7340: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7341: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7342: }
7343: return(0);
7344: }
7346: /*@C
7347: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7349: Collective on Mat
7351: Input Parameters:
7352: + mat - the matrix
7353: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7354: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7355: symmetrized
7356: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7357: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7358: always used.
7359: . n - number of columns in the (possibly compressed) matrix
7360: . ia - the column pointers
7361: - ja - the row indices
7363: Output Parameters:
7364: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7366: Note:
7367: This routine zeros out n, ia, and ja. This is to prevent accidental
7368: us of the array after it has been restored. If you pass NULL, it will
7369: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
7371: Level: developer
7373: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7374: @*/
7375: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7376: {
7386: MatCheckPreallocated(mat,1);
7387: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7388: else {
7389: *done = PETSC_TRUE;
7390: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7391: }
7392: return(0);
7393: }
7395: /*@C
7396: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7397: MatGetRowIJ().
7399: Collective on Mat
7401: Input Parameters:
7402: + mat - the matrix
7403: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7404: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7405: symmetrized
7406: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7407: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7408: always used.
7409: . n - size of (possibly compressed) matrix
7410: . ia - the row pointers
7411: - ja - the column indices
7413: Output Parameters:
7414: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7416: Note:
7417: This routine zeros out n, ia, and ja. This is to prevent accidental
7418: us of the array after it has been restored. If you pass NULL, it will
7419: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7421: Level: developer
7423: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7424: @*/
7425: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7426: {
7435: MatCheckPreallocated(mat,1);
7437: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7438: else {
7439: *done = PETSC_TRUE;
7440: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7441: if (n) *n = 0;
7442: if (ia) *ia = NULL;
7443: if (ja) *ja = NULL;
7444: }
7445: return(0);
7446: }
7448: /*@C
7449: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7450: MatGetColumnIJ().
7452: Collective on Mat
7454: Input Parameters:
7455: + mat - the matrix
7456: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7457: - symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7458: symmetrized
7459: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7460: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7461: always used.
7463: Output Parameters:
7464: + n - size of (possibly compressed) matrix
7465: . ia - the column pointers
7466: . ja - the row indices
7467: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7469: Level: developer
7471: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7472: @*/
7473: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7474: {
7483: MatCheckPreallocated(mat,1);
7485: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7486: else {
7487: *done = PETSC_TRUE;
7488: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7489: if (n) *n = 0;
7490: if (ia) *ia = NULL;
7491: if (ja) *ja = NULL;
7492: }
7493: return(0);
7494: }
7496: /*@C
7497: MatColoringPatch -Used inside matrix coloring routines that
7498: use MatGetRowIJ() and/or MatGetColumnIJ().
7500: Collective on Mat
7502: Input Parameters:
7503: + mat - the matrix
7504: . ncolors - max color value
7505: . n - number of entries in colorarray
7506: - colorarray - array indicating color for each column
7508: Output Parameters:
7509: . iscoloring - coloring generated using colorarray information
7511: Level: developer
7513: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7515: @*/
7516: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7517: {
7525: MatCheckPreallocated(mat,1);
7527: if (!mat->ops->coloringpatch) {
7528: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7529: } else {
7530: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7531: }
7532: return(0);
7533: }
7536: /*@
7537: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7539: Logically Collective on Mat
7541: Input Parameter:
7542: . mat - the factored matrix to be reset
7544: Notes:
7545: This routine should be used only with factored matrices formed by in-place
7546: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7547: format). This option can save memory, for example, when solving nonlinear
7548: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7549: ILU(0) preconditioner.
7551: Note that one can specify in-place ILU(0) factorization by calling
7552: .vb
7553: PCType(pc,PCILU);
7554: PCFactorSeUseInPlace(pc);
7555: .ve
7556: or by using the options -pc_type ilu -pc_factor_in_place
7558: In-place factorization ILU(0) can also be used as a local
7559: solver for the blocks within the block Jacobi or additive Schwarz
7560: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7561: for details on setting local solver options.
7563: Most users should employ the simplified KSP interface for linear solvers
7564: instead of working directly with matrix algebra routines such as this.
7565: See, e.g., KSPCreate().
7567: Level: developer
7569: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7571: Concepts: matrices^unfactored
7573: @*/
7574: PetscErrorCode MatSetUnfactored(Mat mat)
7575: {
7581: MatCheckPreallocated(mat,1);
7582: mat->factortype = MAT_FACTOR_NONE;
7583: if (!mat->ops->setunfactored) return(0);
7584: (*mat->ops->setunfactored)(mat);
7585: return(0);
7586: }
7588: /*MC
7589: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7591: Synopsis:
7592: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7594: Not collective
7596: Input Parameter:
7597: . x - matrix
7599: Output Parameters:
7600: + xx_v - the Fortran90 pointer to the array
7601: - ierr - error code
7603: Example of Usage:
7604: .vb
7605: PetscScalar, pointer xx_v(:,:)
7606: ....
7607: call MatDenseGetArrayF90(x,xx_v,ierr)
7608: a = xx_v(3)
7609: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7610: .ve
7612: Level: advanced
7614: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7616: Concepts: matrices^accessing array
7618: M*/
7620: /*MC
7621: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7622: accessed with MatDenseGetArrayF90().
7624: Synopsis:
7625: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7627: Not collective
7629: Input Parameters:
7630: + x - matrix
7631: - xx_v - the Fortran90 pointer to the array
7633: Output Parameter:
7634: . ierr - error code
7636: Example of Usage:
7637: .vb
7638: PetscScalar, pointer xx_v(:,:)
7639: ....
7640: call MatDenseGetArrayF90(x,xx_v,ierr)
7641: a = xx_v(3)
7642: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7643: .ve
7645: Level: advanced
7647: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7649: M*/
7652: /*MC
7653: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7655: Synopsis:
7656: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7658: Not collective
7660: Input Parameter:
7661: . x - matrix
7663: Output Parameters:
7664: + xx_v - the Fortran90 pointer to the array
7665: - ierr - error code
7667: Example of Usage:
7668: .vb
7669: PetscScalar, pointer xx_v(:)
7670: ....
7671: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7672: a = xx_v(3)
7673: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7674: .ve
7676: Level: advanced
7678: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7680: Concepts: matrices^accessing array
7682: M*/
7684: /*MC
7685: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7686: accessed with MatSeqAIJGetArrayF90().
7688: Synopsis:
7689: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7691: Not collective
7693: Input Parameters:
7694: + x - matrix
7695: - xx_v - the Fortran90 pointer to the array
7697: Output Parameter:
7698: . ierr - error code
7700: Example of Usage:
7701: .vb
7702: PetscScalar, pointer xx_v(:)
7703: ....
7704: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7705: a = xx_v(3)
7706: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7707: .ve
7709: Level: advanced
7711: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7713: M*/
7716: /*@
7717: MatCreateSubMatrix - Gets a single submatrix on the same number of processors
7718: as the original matrix.
7720: Collective on Mat
7722: Input Parameters:
7723: + mat - the original matrix
7724: . isrow - parallel IS containing the rows this processor should obtain
7725: . 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.
7726: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7728: Output Parameter:
7729: . newmat - the new submatrix, of the same type as the old
7731: Level: advanced
7733: Notes:
7734: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7736: Some matrix types place restrictions on the row and column indices, such
7737: as that they be sorted or that they be equal to each other.
7739: The index sets may not have duplicate entries.
7741: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7742: the MatCreateSubMatrix() routine will create the newmat for you. Any additional calls
7743: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7744: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7745: you are finished using it.
7747: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7748: the input matrix.
7750: If iscol is NULL then all columns are obtained (not supported in Fortran).
7752: Example usage:
7753: Consider the following 8x8 matrix with 34 non-zero values, that is
7754: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7755: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7756: as follows:
7758: .vb
7759: 1 2 0 | 0 3 0 | 0 4
7760: Proc0 0 5 6 | 7 0 0 | 8 0
7761: 9 0 10 | 11 0 0 | 12 0
7762: -------------------------------------
7763: 13 0 14 | 15 16 17 | 0 0
7764: Proc1 0 18 0 | 19 20 21 | 0 0
7765: 0 0 0 | 22 23 0 | 24 0
7766: -------------------------------------
7767: Proc2 25 26 27 | 0 0 28 | 29 0
7768: 30 0 0 | 31 32 33 | 0 34
7769: .ve
7771: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7773: .vb
7774: 2 0 | 0 3 0 | 0
7775: Proc0 5 6 | 7 0 0 | 8
7776: -------------------------------
7777: Proc1 18 0 | 19 20 21 | 0
7778: -------------------------------
7779: Proc2 26 27 | 0 0 28 | 29
7780: 0 0 | 31 32 33 | 0
7781: .ve
7784: Concepts: matrices^submatrices
7786: .seealso: MatCreateSubMatrices()
7787: @*/
7788: PetscErrorCode MatCreateSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7789: {
7791: PetscMPIInt size;
7792: Mat *local;
7793: IS iscoltmp;
7802: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7803: if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7805: MatCheckPreallocated(mat,1);
7806: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7808: if (!iscol || isrow == iscol) {
7809: PetscBool stride;
7810: PetscMPIInt grabentirematrix = 0,grab;
7811: PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7812: if (stride) {
7813: PetscInt first,step,n,rstart,rend;
7814: ISStrideGetInfo(isrow,&first,&step);
7815: if (step == 1) {
7816: MatGetOwnershipRange(mat,&rstart,&rend);
7817: if (rstart == first) {
7818: ISGetLocalSize(isrow,&n);
7819: if (n == rend-rstart) {
7820: grabentirematrix = 1;
7821: }
7822: }
7823: }
7824: }
7825: MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7826: if (grab) {
7827: PetscInfo(mat,"Getting entire matrix as submatrix\n");
7828: if (cll == MAT_INITIAL_MATRIX) {
7829: *newmat = mat;
7830: PetscObjectReference((PetscObject)mat);
7831: }
7832: return(0);
7833: }
7834: }
7836: if (!iscol) {
7837: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7838: } else {
7839: iscoltmp = iscol;
7840: }
7842: /* if original matrix is on just one processor then use submatrix generated */
7843: if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7844: MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7845: if (!iscol) {ISDestroy(&iscoltmp);}
7846: return(0);
7847: } else if (mat->ops->createsubmatrices && !mat->ops->createsubmatrix && size == 1) {
7848: MatCreateSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7849: *newmat = *local;
7850: PetscFree(local);
7851: if (!iscol) {ISDestroy(&iscoltmp);}
7852: return(0);
7853: } else if (!mat->ops->createsubmatrix) {
7854: /* Create a new matrix type that implements the operation using the full matrix */
7855: PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7856: switch (cll) {
7857: case MAT_INITIAL_MATRIX:
7858: MatCreateSubMatrixVirtual(mat,isrow,iscoltmp,newmat);
7859: break;
7860: case MAT_REUSE_MATRIX:
7861: MatSubMatrixVirtualUpdate(*newmat,mat,isrow,iscoltmp);
7862: break;
7863: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7864: }
7865: PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7866: if (!iscol) {ISDestroy(&iscoltmp);}
7867: return(0);
7868: }
7870: if (!mat->ops->createsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7871: PetscLogEventBegin(MAT_CreateSubMat,mat,0,0,0);
7872: (*mat->ops->createsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7873: PetscLogEventEnd(MAT_CreateSubMat,mat,0,0,0);
7874: if (!iscol) {ISDestroy(&iscoltmp);}
7875: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7876: return(0);
7877: }
7879: /*@
7880: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7881: used during the assembly process to store values that belong to
7882: other processors.
7884: Not Collective
7886: Input Parameters:
7887: + mat - the matrix
7888: . size - the initial size of the stash.
7889: - bsize - the initial size of the block-stash(if used).
7891: Options Database Keys:
7892: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7893: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7895: Level: intermediate
7897: Notes:
7898: The block-stash is used for values set with MatSetValuesBlocked() while
7899: the stash is used for values set with MatSetValues()
7901: Run with the option -info and look for output of the form
7902: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7903: to determine the appropriate value, MM, to use for size and
7904: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7905: to determine the value, BMM to use for bsize
7907: Concepts: stash^setting matrix size
7908: Concepts: matrices^stash
7910: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7912: @*/
7913: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7914: {
7920: MatStashSetInitialSize_Private(&mat->stash,size);
7921: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7922: return(0);
7923: }
7925: /*@
7926: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7927: the matrix
7929: Neighbor-wise Collective on Mat
7931: Input Parameters:
7932: + mat - the matrix
7933: . x,y - the vectors
7934: - w - where the result is stored
7936: Level: intermediate
7938: Notes:
7939: w may be the same vector as y.
7941: This allows one to use either the restriction or interpolation (its transpose)
7942: matrix to do the interpolation
7944: Concepts: interpolation
7946: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7948: @*/
7949: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7950: {
7952: PetscInt M,N,Ny;
7960: MatCheckPreallocated(A,1);
7961: MatGetSize(A,&M,&N);
7962: VecGetSize(y,&Ny);
7963: if (M == Ny) {
7964: MatMultAdd(A,x,y,w);
7965: } else {
7966: MatMultTransposeAdd(A,x,y,w);
7967: }
7968: return(0);
7969: }
7971: /*@
7972: MatInterpolate - y = A*x or A'*x depending on the shape of
7973: the matrix
7975: Neighbor-wise Collective on Mat
7977: Input Parameters:
7978: + mat - the matrix
7979: - x,y - the vectors
7981: Level: intermediate
7983: Notes:
7984: This allows one to use either the restriction or interpolation (its transpose)
7985: matrix to do the interpolation
7987: Concepts: matrices^interpolation
7989: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7991: @*/
7992: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7993: {
7995: PetscInt M,N,Ny;
8002: MatCheckPreallocated(A,1);
8003: MatGetSize(A,&M,&N);
8004: VecGetSize(y,&Ny);
8005: if (M == Ny) {
8006: MatMult(A,x,y);
8007: } else {
8008: MatMultTranspose(A,x,y);
8009: }
8010: return(0);
8011: }
8013: /*@
8014: MatRestrict - y = A*x or A'*x
8016: Neighbor-wise Collective on Mat
8018: Input Parameters:
8019: + mat - the matrix
8020: - x,y - the vectors
8022: Level: intermediate
8024: Notes:
8025: This allows one to use either the restriction or interpolation (its transpose)
8026: matrix to do the restriction
8028: Concepts: matrices^restriction
8030: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
8032: @*/
8033: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
8034: {
8036: PetscInt M,N,Ny;
8043: MatCheckPreallocated(A,1);
8045: MatGetSize(A,&M,&N);
8046: VecGetSize(y,&Ny);
8047: if (M == Ny) {
8048: MatMult(A,x,y);
8049: } else {
8050: MatMultTranspose(A,x,y);
8051: }
8052: return(0);
8053: }
8055: /*@
8056: MatGetNullSpace - retrieves the null space to a matrix.
8058: Logically Collective on Mat and MatNullSpace
8060: Input Parameters:
8061: + mat - the matrix
8062: - nullsp - the null space object
8064: Level: developer
8066: Concepts: null space^attaching to matrix
8068: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8069: @*/
8070: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8071: {
8076: *nullsp = mat->nullsp;
8077: return(0);
8078: }
8080: /*@
8081: MatSetNullSpace - attaches a null space to a matrix.
8083: Logically Collective on Mat and MatNullSpace
8085: Input Parameters:
8086: + mat - the matrix
8087: - nullsp - the null space object
8089: Level: advanced
8091: Notes:
8092: This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8094: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8095: call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8097: You can remove the null space by calling this routine with an nullsp of NULL
8100: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8101: the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8102: Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8103: n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8104: the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8106: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8108: If the matrix is known to be symmetric because it is an SBAIJ matrix or one as called MatSetOption(mat,MAT_SYMMETRIC or MAT_SYMMETRIC_ETERNAL,PETSC_TRUE); this
8109: routine also automatically calls MatSetTransposeNullSpace().
8111: Concepts: null space^attaching to matrix
8113: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8114: @*/
8115: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8116: {
8123: MatCheckPreallocated(mat,1);
8124: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8125: MatNullSpaceDestroy(&mat->nullsp);
8126: mat->nullsp = nullsp;
8127: if (mat->symmetric_set && mat->symmetric) {
8128: MatSetTransposeNullSpace(mat,nullsp);
8129: }
8130: return(0);
8131: }
8133: /*@
8134: MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8136: Logically Collective on Mat and MatNullSpace
8138: Input Parameters:
8139: + mat - the matrix
8140: - nullsp - the null space object
8142: Level: developer
8144: Concepts: null space^attaching to matrix
8146: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8147: @*/
8148: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8149: {
8154: *nullsp = mat->transnullsp;
8155: return(0);
8156: }
8158: /*@
8159: MatSetTransposeNullSpace - attaches a null space to a matrix.
8161: Logically Collective on Mat and MatNullSpace
8163: Input Parameters:
8164: + mat - the matrix
8165: - nullsp - the null space object
8167: Level: advanced
8169: Notes:
8170: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) this allows the linear system to be solved in a least squares sense.
8171: You must also call MatSetNullSpace()
8174: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8175: the domain of a matrix A (from R^n to R^m (m rows, n columns) R^n = the direct sum of the null space of A, n(A), + the range of A^T, R(A^T).
8176: Similarly R^m = direct sum n(A^T) + R(A). Hence the linear system A x = b has a solution only if b in R(A) (or correspondingly b is orthogonal to
8177: n(A^T)) and if x is a solution then x + alpha n(A) is a solution for any alpha. The minimum norm solution is orthogonal to n(A). For problems without a solution
8178: the solution that minimizes the norm of the residual (the least squares solution) can be obtained by solving A x = \hat{b} where \hat{b} is b orthogonalized to the n(A^T).
8180: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8182: Concepts: null space^attaching to matrix
8184: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8185: @*/
8186: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8187: {
8194: MatCheckPreallocated(mat,1);
8195: PetscObjectReference((PetscObject)nullsp);
8196: MatNullSpaceDestroy(&mat->transnullsp);
8197: mat->transnullsp = nullsp;
8198: return(0);
8199: }
8201: /*@
8202: MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8203: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8205: Logically Collective on Mat and MatNullSpace
8207: Input Parameters:
8208: + mat - the matrix
8209: - nullsp - the null space object
8211: Level: advanced
8213: Notes:
8214: Overwrites any previous near null space that may have been attached
8216: You can remove the null space by calling this routine with an nullsp of NULL
8218: Concepts: null space^attaching to matrix
8220: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8221: @*/
8222: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8223: {
8230: MatCheckPreallocated(mat,1);
8231: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8232: MatNullSpaceDestroy(&mat->nearnullsp);
8233: mat->nearnullsp = nullsp;
8234: return(0);
8235: }
8237: /*@
8238: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8240: Not Collective
8242: Input Parameters:
8243: . mat - the matrix
8245: Output Parameters:
8246: . nullsp - the null space object, NULL if not set
8248: Level: developer
8250: Concepts: null space^attaching to matrix
8252: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8253: @*/
8254: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8255: {
8260: MatCheckPreallocated(mat,1);
8261: *nullsp = mat->nearnullsp;
8262: return(0);
8263: }
8265: /*@C
8266: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8268: Collective on Mat
8270: Input Parameters:
8271: + mat - the matrix
8272: . row - row/column permutation
8273: . fill - expected fill factor >= 1.0
8274: - level - level of fill, for ICC(k)
8276: Notes:
8277: Probably really in-place only when level of fill is zero, otherwise allocates
8278: new space to store factored matrix and deletes previous memory.
8280: Most users should employ the simplified KSP interface for linear solvers
8281: instead of working directly with matrix algebra routines such as this.
8282: See, e.g., KSPCreate().
8284: Level: developer
8286: Concepts: matrices^incomplete Cholesky factorization
8287: Concepts: Cholesky factorization
8289: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8291: Developer Note: fortran interface is not autogenerated as the f90
8292: interface defintion cannot be generated correctly [due to MatFactorInfo]
8294: @*/
8295: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8296: {
8304: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8305: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8306: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8307: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8308: MatCheckPreallocated(mat,1);
8309: (*mat->ops->iccfactor)(mat,row,info);
8310: PetscObjectStateIncrease((PetscObject)mat);
8311: return(0);
8312: }
8314: /*@
8315: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8316: ghosted ones.
8318: Not Collective
8320: Input Parameters:
8321: + mat - the matrix
8322: - diag = the diagonal values, including ghost ones
8324: Level: developer
8326: Notes: Works only for MPIAIJ and MPIBAIJ matrices
8328: .seealso: MatDiagonalScale()
8329: @*/
8330: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8331: {
8333: PetscMPIInt size;
8340: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8341: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8342: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8343: if (size == 1) {
8344: PetscInt n,m;
8345: VecGetSize(diag,&n);
8346: MatGetSize(mat,0,&m);
8347: if (m == n) {
8348: MatDiagonalScale(mat,0,diag);
8349: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8350: } else {
8351: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8352: }
8353: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8354: PetscObjectStateIncrease((PetscObject)mat);
8355: return(0);
8356: }
8358: /*@
8359: MatGetInertia - Gets the inertia from a factored matrix
8361: Collective on Mat
8363: Input Parameter:
8364: . mat - the matrix
8366: Output Parameters:
8367: + nneg - number of negative eigenvalues
8368: . nzero - number of zero eigenvalues
8369: - npos - number of positive eigenvalues
8371: Level: advanced
8373: Notes: Matrix must have been factored by MatCholeskyFactor()
8376: @*/
8377: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8378: {
8384: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8385: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8386: if (!mat->ops->getinertia) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8387: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8388: return(0);
8389: }
8391: /* ----------------------------------------------------------------*/
8392: /*@C
8393: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8395: Neighbor-wise Collective on Mat and Vecs
8397: Input Parameters:
8398: + mat - the factored matrix
8399: - b - the right-hand-side vectors
8401: Output Parameter:
8402: . x - the result vectors
8404: Notes:
8405: The vectors b and x cannot be the same. I.e., one cannot
8406: call MatSolves(A,x,x).
8408: Notes:
8409: Most users should employ the simplified KSP interface for linear solvers
8410: instead of working directly with matrix algebra routines such as this.
8411: See, e.g., KSPCreate().
8413: Level: developer
8415: Concepts: matrices^triangular solves
8417: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8418: @*/
8419: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8420: {
8426: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8427: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8428: if (!mat->rmap->N && !mat->cmap->N) return(0);
8430: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8431: MatCheckPreallocated(mat,1);
8432: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8433: (*mat->ops->solves)(mat,b,x);
8434: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8435: return(0);
8436: }
8438: /*@
8439: MatIsSymmetric - Test whether a matrix is symmetric
8441: Collective on Mat
8443: Input Parameter:
8444: + A - the matrix to test
8445: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8447: Output Parameters:
8448: . flg - the result
8450: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8452: Level: intermediate
8454: Concepts: matrix^symmetry
8456: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8457: @*/
8458: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8459: {
8466: if (!A->symmetric_set) {
8467: if (!A->ops->issymmetric) {
8468: MatType mattype;
8469: MatGetType(A,&mattype);
8470: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8471: }
8472: (*A->ops->issymmetric)(A,tol,flg);
8473: if (!tol) {
8474: A->symmetric_set = PETSC_TRUE;
8475: A->symmetric = *flg;
8476: if (A->symmetric) {
8477: A->structurally_symmetric_set = PETSC_TRUE;
8478: A->structurally_symmetric = PETSC_TRUE;
8479: }
8480: }
8481: } else if (A->symmetric) {
8482: *flg = PETSC_TRUE;
8483: } else if (!tol) {
8484: *flg = PETSC_FALSE;
8485: } else {
8486: if (!A->ops->issymmetric) {
8487: MatType mattype;
8488: MatGetType(A,&mattype);
8489: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8490: }
8491: (*A->ops->issymmetric)(A,tol,flg);
8492: }
8493: return(0);
8494: }
8496: /*@
8497: MatIsHermitian - Test whether a matrix is Hermitian
8499: Collective on Mat
8501: Input Parameter:
8502: + A - the matrix to test
8503: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8505: Output Parameters:
8506: . flg - the result
8508: Level: intermediate
8510: Concepts: matrix^symmetry
8512: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8513: MatIsSymmetricKnown(), MatIsSymmetric()
8514: @*/
8515: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8516: {
8523: if (!A->hermitian_set) {
8524: if (!A->ops->ishermitian) {
8525: MatType mattype;
8526: MatGetType(A,&mattype);
8527: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8528: }
8529: (*A->ops->ishermitian)(A,tol,flg);
8530: if (!tol) {
8531: A->hermitian_set = PETSC_TRUE;
8532: A->hermitian = *flg;
8533: if (A->hermitian) {
8534: A->structurally_symmetric_set = PETSC_TRUE;
8535: A->structurally_symmetric = PETSC_TRUE;
8536: }
8537: }
8538: } else if (A->hermitian) {
8539: *flg = PETSC_TRUE;
8540: } else if (!tol) {
8541: *flg = PETSC_FALSE;
8542: } else {
8543: if (!A->ops->ishermitian) {
8544: MatType mattype;
8545: MatGetType(A,&mattype);
8546: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8547: }
8548: (*A->ops->ishermitian)(A,tol,flg);
8549: }
8550: return(0);
8551: }
8553: /*@
8554: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8556: Not Collective
8558: Input Parameter:
8559: . A - the matrix to check
8561: Output Parameters:
8562: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8563: - flg - the result
8565: Level: advanced
8567: Concepts: matrix^symmetry
8569: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8570: if you want it explicitly checked
8572: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8573: @*/
8574: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8575: {
8580: if (A->symmetric_set) {
8581: *set = PETSC_TRUE;
8582: *flg = A->symmetric;
8583: } else {
8584: *set = PETSC_FALSE;
8585: }
8586: return(0);
8587: }
8589: /*@
8590: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8592: Not Collective
8594: Input Parameter:
8595: . A - the matrix to check
8597: Output Parameters:
8598: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8599: - flg - the result
8601: Level: advanced
8603: Concepts: matrix^symmetry
8605: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8606: if you want it explicitly checked
8608: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8609: @*/
8610: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8611: {
8616: if (A->hermitian_set) {
8617: *set = PETSC_TRUE;
8618: *flg = A->hermitian;
8619: } else {
8620: *set = PETSC_FALSE;
8621: }
8622: return(0);
8623: }
8625: /*@
8626: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8628: Collective on Mat
8630: Input Parameter:
8631: . A - the matrix to test
8633: Output Parameters:
8634: . flg - the result
8636: Level: intermediate
8638: Concepts: matrix^symmetry
8640: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8641: @*/
8642: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8643: {
8649: if (!A->structurally_symmetric_set) {
8650: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8651: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8653: A->structurally_symmetric_set = PETSC_TRUE;
8654: }
8655: *flg = A->structurally_symmetric;
8656: return(0);
8657: }
8659: /*@
8660: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8661: to be communicated to other processors during the MatAssemblyBegin/End() process
8663: Not collective
8665: Input Parameter:
8666: . vec - the vector
8668: Output Parameters:
8669: + nstash - the size of the stash
8670: . reallocs - the number of additional mallocs incurred.
8671: . bnstash - the size of the block stash
8672: - breallocs - the number of additional mallocs incurred.in the block stash
8674: Level: advanced
8676: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8678: @*/
8679: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8680: {
8684: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8685: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8686: return(0);
8687: }
8689: /*@C
8690: MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8691: parallel layout
8693: Collective on Mat
8695: Input Parameter:
8696: . mat - the matrix
8698: Output Parameter:
8699: + right - (optional) vector that the matrix can be multiplied against
8700: - left - (optional) vector that the matrix vector product can be stored in
8702: Notes:
8703: The blocksize of the returned vectors is determined by the row and column block sizes set with MatSetBlockSizes() or the single blocksize (same for both) set by MatSetBlockSize().
8705: Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8707: Level: advanced
8709: .seealso: MatCreate(), VecDestroy()
8710: @*/
8711: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8712: {
8718: if (mat->ops->getvecs) {
8719: (*mat->ops->getvecs)(mat,right,left);
8720: } else {
8721: PetscInt rbs,cbs;
8722: MatGetBlockSizes(mat,&rbs,&cbs);
8723: if (right) {
8724: if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8725: VecCreate(PetscObjectComm((PetscObject)mat),right);
8726: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8727: VecSetBlockSize(*right,cbs);
8728: VecSetType(*right,VECSTANDARD);
8729: PetscLayoutReference(mat->cmap,&(*right)->map);
8730: }
8731: if (left) {
8732: if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8733: VecCreate(PetscObjectComm((PetscObject)mat),left);
8734: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8735: VecSetBlockSize(*left,rbs);
8736: VecSetType(*left,VECSTANDARD);
8737: PetscLayoutReference(mat->rmap,&(*left)->map);
8738: }
8739: }
8740: return(0);
8741: }
8743: /*@C
8744: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8745: with default values.
8747: Not Collective
8749: Input Parameters:
8750: . info - the MatFactorInfo data structure
8753: Notes: The solvers are generally used through the KSP and PC objects, for example
8754: PCLU, PCILU, PCCHOLESKY, PCICC
8756: Level: developer
8758: .seealso: MatFactorInfo
8760: Developer Note: fortran interface is not autogenerated as the f90
8761: interface defintion cannot be generated correctly [due to MatFactorInfo]
8763: @*/
8765: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8766: {
8770: PetscMemzero(info,sizeof(MatFactorInfo));
8771: return(0);
8772: }
8774: /*@
8775: MatFactorSetSchurIS - Set indices corresponding to the Schur complement you wish to have computed
8777: Collective on Mat
8779: Input Parameters:
8780: + mat - the factored matrix
8781: - is - the index set defining the Schur indices (0-based)
8783: Notes: Call MatFactorSolveSchurComplement() or MatFactorSolveSchurComplementTranspose() after this call to solve a Schur complement system.
8785: You can call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() after this call.
8787: Level: developer
8789: Concepts:
8791: .seealso: MatGetFactor(), MatFactorGetSchurComplement(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSolveSchurComplement(),
8792: MatFactorSolveSchurComplementTranspose(), MatFactorSolveSchurComplement()
8794: @*/
8795: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8796: {
8797: PetscErrorCode ierr,(*f)(Mat,IS);
8805: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8806: PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8807: if (!f) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"The selected MatSolverPackage does not support Schur complement computation. You should use MATSOLVERMUMPS or MATSOLVERMKL_PARDISO");
8808: if (mat->schur) {
8809: MatDestroy(&mat->schur);
8810: }
8811: (*f)(mat,is);
8812: if (!mat->schur) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_PLIB,"Schur complement has not been created");
8813: MatFactorSetUpInPlaceSchur_Private(mat);
8814: return(0);
8815: }
8817: /*@
8818: MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8820: Logically Collective on Mat
8822: Input Parameters:
8823: + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8824: . S - location where to return the Schur complement, can be NULL
8825: - status - the status of the Schur complement matrix, can be NULL
8827: Notes:
8828: You must call MatFactorSetSchurIS() before calling this routine.
8830: The routine provides a copy of the Schur matrix stored within the solver data structures.
8831: The caller must destroy the object when it is no longer needed.
8832: If MatFactorInvertSchurComplement() has been called, the routine gets back the inverse.
8834: Use MatFactorGetSchurComplement() to get access to the Schur complement matrix inside the factored matrix instead of making a copy of it (which this function does)
8836: Developer Notes: The reason this routine exists is because the representation of the Schur complement within the factor matrix may be different than a standard PETSc
8837: matrix representation and we normally do not want to use the time or memory to make a copy as a regular PETSc matrix.
8839: See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8841: Level: advanced
8843: References:
8845: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorSchurStatus
8846: @*/
8847: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8848: {
8855: if (S) {
8856: PetscErrorCode (*f)(Mat,Mat*);
8858: PetscObjectQueryFunction((PetscObject)F,"MatFactorCreateSchurComplement_C",&f);
8859: if (f) {
8860: (*f)(F,S);
8861: } else {
8862: MatDuplicate(F->schur,MAT_COPY_VALUES,S);
8863: }
8864: }
8865: if (status) *status = F->schur_status;
8866: return(0);
8867: }
8869: /*@
8870: MatFactorGetSchurComplement - Gets access to a Schur complement matrix using the current Schur data within a factored matrix
8872: Logically Collective on Mat
8874: Input Parameters:
8875: + F - the factored matrix obtained by calling MatGetFactor()
8876: . *S - location where to return the Schur complement, can be NULL
8877: - status - the status of the Schur complement matrix, can be NULL
8879: Notes:
8880: You must call MatFactorSetSchurIS() before calling this routine.
8882: Schur complement mode is currently implemented for sequential matrices.
8883: The routine returns a the Schur Complement stored within the data strutures of the solver.
8884: If MatFactorInvertSchurComplement() has previously been called, the returned matrix is actually the inverse of the Schur complement.
8885: The returned matrix should not be destroyed; the caller should call MatFactorRestoreSchurComplement() when the object is no longer needed.
8887: Use MatFactorCreateSchurComplement() to create a copy of the Schur complement matrix that is within a factored matrix
8889: See MatCreateSchurComplement() or MatGetSchurComplement() for ways to create virtual or approximate Schur complements.
8891: Level: advanced
8893: References:
8895: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8896: @*/
8897: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S,MatFactorSchurStatus* status)
8898: {
8903: if (S) *S = F->schur;
8904: if (status) *status = F->schur_status;
8905: return(0);
8906: }
8908: /*@
8909: MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8911: Logically Collective on Mat
8913: Input Parameters:
8914: + F - the factored matrix obtained by calling MatGetFactor()
8915: . *S - location where the Schur complement is stored
8916: - status - the status of the Schur complement matrix (see MatFactorSchurStatus)
8918: Notes:
8920: Level: advanced
8922: References:
8924: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement(), MatFactorSchurStatus
8925: @*/
8926: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S,MatFactorSchurStatus status)
8927: {
8932: if (S) {
8934: *S = NULL;
8935: }
8936: F->schur_status = status;
8937: MatFactorUpdateSchurStatus_Private(F);
8938: return(0);
8939: }
8941: /*@
8942: MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8944: Logically Collective on Mat
8946: Input Parameters:
8947: + F - the factored matrix obtained by calling MatGetFactor()
8948: . rhs - location where the right hand side of the Schur complement system is stored
8949: - sol - location where the solution of the Schur complement system has to be returned
8951: Notes:
8952: The sizes of the vectors should match the size of the Schur complement
8954: Must be called after MatFactorSetSchurIS()
8956: Level: advanced
8958: References:
8960: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplement()
8961: @*/
8962: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8963: {
8975: MatFactorFactorizeSchurComplement(F);
8976: switch (F->schur_status) {
8977: case MAT_FACTOR_SCHUR_FACTORED:
8978: MatSolveTranspose(F->schur,rhs,sol);
8979: break;
8980: case MAT_FACTOR_SCHUR_INVERTED:
8981: MatMultTranspose(F->schur,rhs,sol);
8982: break;
8983: default:
8984: SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
8985: break;
8986: }
8987: return(0);
8988: }
8990: /*@
8991: MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8993: Logically Collective on Mat
8995: Input Parameters:
8996: + F - the factored matrix obtained by calling MatGetFactor()
8997: . rhs - location where the right hand side of the Schur complement system is stored
8998: - sol - location where the solution of the Schur complement system has to be returned
9000: Notes:
9001: The sizes of the vectors should match the size of the Schur complement
9003: Must be called after MatFactorSetSchurIS()
9005: Level: advanced
9007: References:
9009: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorSolveSchurComplementTranspose()
9010: @*/
9011: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
9012: {
9024: MatFactorFactorizeSchurComplement(F);
9025: switch (F->schur_status) {
9026: case MAT_FACTOR_SCHUR_FACTORED:
9027: MatSolve(F->schur,rhs,sol);
9028: break;
9029: case MAT_FACTOR_SCHUR_INVERTED:
9030: MatMult(F->schur,rhs,sol);
9031: break;
9032: default:
9033: SETERRQ1(PetscObjectComm((PetscObject)F),PETSC_ERR_SUP,"Unhandled MatFactorSchurStatus %D",F->schur_status);
9034: break;
9035: }
9036: return(0);
9037: }
9039: /*@
9040: MatFactorInvertSchurComplement - Invert the Schur complement matrix computed during the factorization step
9042: Logically Collective on Mat
9044: Input Parameters:
9045: + F - the factored matrix obtained by calling MatGetFactor()
9047: Notes: Must be called after MatFactorSetSchurIS().
9049: Call MatFactorGetSchurComplement() or MatFactorCreateSchurComplement() AFTER this call to actually compute the inverse and get access to it.
9051: Level: advanced
9053: References:
9055: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement(), MatFactorCreateSchurComplement()
9056: @*/
9057: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9058: {
9064: if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED) return(0);
9065: MatFactorFactorizeSchurComplement(F);
9066: MatFactorInvertSchurComplement_Private(F);
9067: F->schur_status = MAT_FACTOR_SCHUR_INVERTED;
9068: return(0);
9069: }
9071: /*@
9072: MatFactorFactorizeSchurComplement - Factorize the Schur complement matrix computed during the factorization step
9074: Logically Collective on Mat
9076: Input Parameters:
9077: + F - the factored matrix obtained by calling MatGetFactor()
9079: Notes: Must be called after MatFactorSetSchurIS().
9081: Level: advanced
9083: References:
9085: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorInvertSchurComplement()
9086: @*/
9087: PetscErrorCode MatFactorFactorizeSchurComplement(Mat F)
9088: {
9094: if (F->schur_status == MAT_FACTOR_SCHUR_INVERTED || F->schur_status == MAT_FACTOR_SCHUR_FACTORED) return(0);
9095: MatFactorFactorizeSchurComplement_Private(F);
9096: F->schur_status = MAT_FACTOR_SCHUR_FACTORED;
9097: return(0);
9098: }
9100: /*@
9101: MatPtAP - Creates the matrix product C = P^T * A * P
9103: Neighbor-wise Collective on Mat
9105: Input Parameters:
9106: + A - the matrix
9107: . P - the projection matrix
9108: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9109: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9110: if the result is a dense matrix this is irrelevent
9112: Output Parameters:
9113: . C - the product matrix
9115: Notes:
9116: C will be created and must be destroyed by the user with MatDestroy().
9118: This routine is currently only implemented for pairs of AIJ matrices and classes
9119: which inherit from AIJ.
9121: Level: intermediate
9123: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9124: @*/
9125: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9126: {
9128: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9129: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9130: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9131: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9134: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9135: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
9139: MatCheckPreallocated(A,1);
9140: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9141: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9142: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9145: MatCheckPreallocated(P,2);
9146: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9147: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9149: 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);
9150: 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);
9151: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9152: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9154: if (scall == MAT_REUSE_MATRIX) {
9157: if (viatranspose || viamatmatmatmult) {
9158: Mat Pt;
9159: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9160: if (viamatmatmatmult) {
9161: MatMatMatMult(Pt,A,P,scall,fill,C);
9162: } else {
9163: Mat AP;
9164: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9165: MatMatMult(Pt,AP,scall,fill,C);
9166: MatDestroy(&AP);
9167: }
9168: MatDestroy(&Pt);
9169: } else {
9170: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9171: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9172: (*(*C)->ops->ptapnumeric)(A,P,*C);
9173: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9174: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9175: }
9176: return(0);
9177: }
9179: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9180: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9182: fA = A->ops->ptap;
9183: fP = P->ops->ptap;
9184: if (fP == fA) {
9185: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9186: ptap = fA;
9187: } else {
9188: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9189: char ptapname[256];
9190: PetscStrcpy(ptapname,"MatPtAP_");
9191: PetscStrcat(ptapname,((PetscObject)A)->type_name);
9192: PetscStrcat(ptapname,"_");
9193: PetscStrcat(ptapname,((PetscObject)P)->type_name);
9194: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9195: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9196: 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);
9197: }
9199: if (viatranspose || viamatmatmatmult) {
9200: Mat Pt;
9201: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9202: if (viamatmatmatmult) {
9203: MatMatMatMult(Pt,A,P,scall,fill,C);
9204: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9205: } else {
9206: Mat AP;
9207: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9208: MatMatMult(Pt,AP,scall,fill,C);
9209: MatDestroy(&AP);
9210: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9211: }
9212: MatDestroy(&Pt);
9213: } else {
9214: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9215: (*ptap)(A,P,scall,fill,C);
9216: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9217: }
9218: return(0);
9219: }
9221: /*@
9222: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9224: Neighbor-wise Collective on Mat
9226: Input Parameters:
9227: + A - the matrix
9228: - P - the projection matrix
9230: Output Parameters:
9231: . C - the product matrix
9233: Notes:
9234: C must have been created by calling MatPtAPSymbolic and must be destroyed by
9235: the user using MatDeatroy().
9237: This routine is currently only implemented for pairs of AIJ matrices and classes
9238: which inherit from AIJ. C will be of type MATAIJ.
9240: Level: intermediate
9242: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9243: @*/
9244: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9245: {
9251: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9252: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9255: MatCheckPreallocated(P,2);
9256: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9257: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9260: MatCheckPreallocated(C,3);
9261: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9262: 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);
9263: 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);
9264: 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);
9265: 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);
9266: MatCheckPreallocated(A,1);
9268: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9269: (*C->ops->ptapnumeric)(A,P,C);
9270: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9271: return(0);
9272: }
9274: /*@
9275: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9277: Neighbor-wise Collective on Mat
9279: Input Parameters:
9280: + A - the matrix
9281: - P - the projection matrix
9283: Output Parameters:
9284: . C - the (i,j) structure of the product matrix
9286: Notes:
9287: C will be created and must be destroyed by the user with MatDestroy().
9289: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9290: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9291: this (i,j) structure by calling MatPtAPNumeric().
9293: Level: intermediate
9295: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9296: @*/
9297: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9298: {
9304: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9305: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9306: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9309: MatCheckPreallocated(P,2);
9310: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9311: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9314: 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);
9315: 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);
9316: MatCheckPreallocated(A,1);
9317: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9318: (*A->ops->ptapsymbolic)(A,P,fill,C);
9319: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
9321: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9322: return(0);
9323: }
9325: /*@
9326: MatRARt - Creates the matrix product C = R * A * R^T
9328: Neighbor-wise Collective on Mat
9330: Input Parameters:
9331: + A - the matrix
9332: . R - the projection matrix
9333: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9334: - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9335: if the result is a dense matrix this is irrelevent
9337: Output Parameters:
9338: . C - the product matrix
9340: Notes:
9341: C will be created and must be destroyed by the user with MatDestroy().
9343: This routine is currently only implemented for pairs of AIJ matrices and classes
9344: which inherit from AIJ. Due to PETSc sparse matrix block row distribution among processes,
9345: parallel MatRARt is implemented via explicit transpose of R, which could be very expensive.
9346: We recommend using MatPtAP().
9348: Level: intermediate
9350: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9351: @*/
9352: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9353: {
9359: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9360: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9361: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9364: MatCheckPreallocated(R,2);
9365: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9366: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9368: 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);
9370: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9371: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9372: MatCheckPreallocated(A,1);
9374: if (!A->ops->rart) {
9375: Mat Rt;
9376: MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);
9377: MatMatMatMult(R,A,Rt,scall,fill,C);
9378: MatDestroy(&Rt);
9379: }
9380: PetscLogEventBegin(MAT_RARt,A,R,0,0);
9381: (*A->ops->rart)(A,R,scall,fill,C);
9382: PetscLogEventEnd(MAT_RARt,A,R,0,0);
9383: return(0);
9384: }
9386: /*@
9387: MatRARtNumeric - Computes the matrix product C = R * A * R^T
9389: Neighbor-wise Collective on Mat
9391: Input Parameters:
9392: + A - the matrix
9393: - R - the projection matrix
9395: Output Parameters:
9396: . C - the product matrix
9398: Notes:
9399: C must have been created by calling MatRARtSymbolic and must be destroyed by
9400: the user using MatDestroy().
9402: This routine is currently only implemented for pairs of AIJ matrices and classes
9403: which inherit from AIJ. C will be of type MATAIJ.
9405: Level: intermediate
9407: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9408: @*/
9409: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9410: {
9416: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9417: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9420: MatCheckPreallocated(R,2);
9421: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9422: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9425: MatCheckPreallocated(C,3);
9426: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9427: 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);
9428: 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);
9429: 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);
9430: 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);
9431: MatCheckPreallocated(A,1);
9433: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9434: (*A->ops->rartnumeric)(A,R,C);
9435: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9436: return(0);
9437: }
9439: /*@
9440: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9442: Neighbor-wise Collective on Mat
9444: Input Parameters:
9445: + A - the matrix
9446: - R - the projection matrix
9448: Output Parameters:
9449: . C - the (i,j) structure of the product matrix
9451: Notes:
9452: C will be created and must be destroyed by the user with MatDestroy().
9454: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9455: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9456: this (i,j) structure by calling MatRARtNumeric().
9458: Level: intermediate
9460: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9461: @*/
9462: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9463: {
9469: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9470: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9471: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9474: MatCheckPreallocated(R,2);
9475: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9476: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9479: 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);
9480: 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);
9481: MatCheckPreallocated(A,1);
9482: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9483: (*A->ops->rartsymbolic)(A,R,fill,C);
9484: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9486: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9487: return(0);
9488: }
9490: /*@
9491: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9493: Neighbor-wise Collective on Mat
9495: Input Parameters:
9496: + A - the left matrix
9497: . B - the right matrix
9498: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9499: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9500: if the result is a dense matrix this is irrelevent
9502: Output Parameters:
9503: . C - the product matrix
9505: Notes:
9506: Unless scall is MAT_REUSE_MATRIX C will be created.
9508: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call and C was obtained from a previous
9509: call to this function with either MAT_INITIAL_MATRIX or MatMatMultSymbolic()
9511: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9512: actually needed.
9514: If you have many matrices with the same non-zero structure to multiply, you
9515: should either
9516: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9517: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9518: In the special case where matrix B (and hence C) are dense you can create the correctly sized matrix C yourself and then call this routine
9519: with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9521: Level: intermediate
9523: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9524: @*/
9525: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9526: {
9528: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9529: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9530: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9535: MatCheckPreallocated(A,1);
9536: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9537: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9540: MatCheckPreallocated(B,2);
9541: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9542: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9544: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9545: 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);
9546: if (scall == MAT_REUSE_MATRIX) {
9549: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9550: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9551: (*(*C)->ops->matmultnumeric)(A,B,*C);
9552: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9553: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9554: return(0);
9555: }
9556: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9557: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9559: fA = A->ops->matmult;
9560: fB = B->ops->matmult;
9561: if (fB == fA) {
9562: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9563: mult = fB;
9564: } else {
9565: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9566: char multname[256];
9567: PetscStrcpy(multname,"MatMatMult_");
9568: PetscStrcat(multname,((PetscObject)A)->type_name);
9569: PetscStrcat(multname,"_");
9570: PetscStrcat(multname,((PetscObject)B)->type_name);
9571: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9572: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9573: 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);
9574: }
9575: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9576: (*mult)(A,B,scall,fill,C);
9577: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9578: return(0);
9579: }
9581: /*@
9582: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9583: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
9585: Neighbor-wise Collective on Mat
9587: Input Parameters:
9588: + A - the left matrix
9589: . B - the right matrix
9590: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9591: if C is a dense matrix this is irrelevent
9593: Output Parameters:
9594: . C - the product matrix
9596: Notes:
9597: Unless scall is MAT_REUSE_MATRIX C will be created.
9599: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9600: actually needed.
9602: This routine is currently implemented for
9603: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9604: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9605: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9607: Level: intermediate
9609: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9610: We should incorporate them into PETSc.
9612: .seealso: MatMatMult(), MatMatMultNumeric()
9613: @*/
9614: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9615: {
9617: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9618: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9619: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9624: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9625: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9629: MatCheckPreallocated(B,2);
9630: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9631: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9634: 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);
9635: if (fill == PETSC_DEFAULT) fill = 2.0;
9636: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9637: MatCheckPreallocated(A,1);
9639: Asymbolic = A->ops->matmultsymbolic;
9640: Bsymbolic = B->ops->matmultsymbolic;
9641: if (Asymbolic == Bsymbolic) {
9642: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9643: symbolic = Bsymbolic;
9644: } else { /* dispatch based on the type of A and B */
9645: char symbolicname[256];
9646: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9647: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9648: PetscStrcat(symbolicname,"_");
9649: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9650: PetscStrcat(symbolicname,"_C");
9651: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9652: 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);
9653: }
9654: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9655: (*symbolic)(A,B,fill,C);
9656: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9657: return(0);
9658: }
9660: /*@
9661: MatMatMultNumeric - Performs the numeric matrix-matrix product.
9662: Call this routine after first calling MatMatMultSymbolic().
9664: Neighbor-wise Collective on Mat
9666: Input Parameters:
9667: + A - the left matrix
9668: - B - the right matrix
9670: Output Parameters:
9671: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9673: Notes:
9674: C must have been created with MatMatMultSymbolic().
9676: This routine is currently implemented for
9677: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9678: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9679: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9681: Level: intermediate
9683: .seealso: MatMatMult(), MatMatMultSymbolic()
9684: @*/
9685: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9686: {
9690: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9691: return(0);
9692: }
9694: /*@
9695: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9697: Neighbor-wise Collective on Mat
9699: Input Parameters:
9700: + A - the left matrix
9701: . B - the right matrix
9702: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9703: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9705: Output Parameters:
9706: . C - the product matrix
9708: Notes:
9709: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9711: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9713: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9714: actually needed.
9716: This routine is currently only implemented for pairs of SeqAIJ matrices and for the SeqDense class.
9718: Level: intermediate
9720: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9721: @*/
9722: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9723: {
9725: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9726: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9731: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9732: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9733: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9736: MatCheckPreallocated(B,2);
9737: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9738: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9740: 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);
9741: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9742: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9743: MatCheckPreallocated(A,1);
9745: fA = A->ops->mattransposemult;
9746: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9747: fB = B->ops->mattransposemult;
9748: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9749: 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);
9751: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9752: if (scall == MAT_INITIAL_MATRIX) {
9753: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9754: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9755: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9756: }
9757: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9758: (*A->ops->mattransposemultnumeric)(A,B,*C);
9759: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9760: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9761: return(0);
9762: }
9764: /*@
9765: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9767: Neighbor-wise Collective on Mat
9769: Input Parameters:
9770: + A - the left matrix
9771: . B - the right matrix
9772: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9773: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9775: Output Parameters:
9776: . C - the product matrix
9778: Notes:
9779: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9781: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9783: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9784: actually needed.
9786: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9787: which inherit from SeqAIJ. C will be of same type as the input matrices.
9789: Level: intermediate
9791: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9792: @*/
9793: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9794: {
9796: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9797: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9798: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9803: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9804: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9805: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9808: MatCheckPreallocated(B,2);
9809: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9810: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9812: 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);
9813: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9814: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9815: MatCheckPreallocated(A,1);
9817: fA = A->ops->transposematmult;
9818: fB = B->ops->transposematmult;
9819: if (fB==fA) {
9820: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9821: transposematmult = fA;
9822: } else {
9823: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9824: char multname[256];
9825: PetscStrcpy(multname,"MatTransposeMatMult_");
9826: PetscStrcat(multname,((PetscObject)A)->type_name);
9827: PetscStrcat(multname,"_");
9828: PetscStrcat(multname,((PetscObject)B)->type_name);
9829: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9830: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9831: 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);
9832: }
9833: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9834: (*transposematmult)(A,B,scall,fill,C);
9835: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9836: return(0);
9837: }
9839: /*@
9840: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9842: Neighbor-wise Collective on Mat
9844: Input Parameters:
9845: + A - the left matrix
9846: . B - the middle matrix
9847: . C - the right matrix
9848: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9849: - 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
9850: if the result is a dense matrix this is irrelevent
9852: Output Parameters:
9853: . D - the product matrix
9855: Notes:
9856: Unless scall is MAT_REUSE_MATRIX D will be created.
9858: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9860: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9861: actually needed.
9863: If you have many matrices with the same non-zero structure to multiply, you
9864: should use MAT_REUSE_MATRIX in all calls but the first or
9866: Level: intermediate
9868: .seealso: MatMatMult, MatPtAP()
9869: @*/
9870: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9871: {
9873: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9874: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9875: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9876: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9881: MatCheckPreallocated(A,1);
9882: if (scall == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
9883: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9884: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9887: MatCheckPreallocated(B,2);
9888: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9889: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9892: MatCheckPreallocated(C,3);
9893: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9894: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9895: 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);
9896: 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);
9897: if (scall == MAT_REUSE_MATRIX) {
9900: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9901: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9902: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9903: return(0);
9904: }
9905: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9906: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9908: fA = A->ops->matmatmult;
9909: fB = B->ops->matmatmult;
9910: fC = C->ops->matmatmult;
9911: if (fA == fB && fA == fC) {
9912: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9913: mult = fA;
9914: } else {
9915: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9916: char multname[256];
9917: PetscStrcpy(multname,"MatMatMatMult_");
9918: PetscStrcat(multname,((PetscObject)A)->type_name);
9919: PetscStrcat(multname,"_");
9920: PetscStrcat(multname,((PetscObject)B)->type_name);
9921: PetscStrcat(multname,"_");
9922: PetscStrcat(multname,((PetscObject)C)->type_name);
9923: PetscStrcat(multname,"_C");
9924: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9925: 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);
9926: }
9927: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9928: (*mult)(A,B,C,scall,fill,D);
9929: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9930: return(0);
9931: }
9933: /*@
9934: MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9936: Collective on Mat
9938: Input Parameters:
9939: + mat - the matrix
9940: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9941: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9942: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9944: Output Parameter:
9945: . matredundant - redundant matrix
9947: Notes:
9948: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9949: original matrix has not changed from that last call to MatCreateRedundantMatrix().
9951: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9952: calling it.
9954: Level: advanced
9956: Concepts: subcommunicator
9957: Concepts: duplicate matrix
9959: .seealso: MatDestroy()
9960: @*/
9961: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9962: {
9964: MPI_Comm comm;
9965: PetscMPIInt size;
9966: PetscInt mloc_sub,nloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9967: Mat_Redundant *redund=NULL;
9968: PetscSubcomm psubcomm=NULL;
9969: MPI_Comm subcomm_in=subcomm;
9970: Mat *matseq;
9971: IS isrow,iscol;
9972: PetscBool newsubcomm=PETSC_FALSE;
9976: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9979: }
9981: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9982: if (size == 1 || nsubcomm == 1) {
9983: if (reuse == MAT_INITIAL_MATRIX) {
9984: MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9985: } else {
9986: if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
9987: MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9988: }
9989: return(0);
9990: }
9992: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9993: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9994: MatCheckPreallocated(mat,1);
9996: PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9997: if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9998: /* create psubcomm, then get subcomm */
9999: PetscObjectGetComm((PetscObject)mat,&comm);
10000: MPI_Comm_size(comm,&size);
10001: if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
10003: PetscSubcommCreate(comm,&psubcomm);
10004: PetscSubcommSetNumber(psubcomm,nsubcomm);
10005: PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
10006: PetscSubcommSetFromOptions(psubcomm);
10007: PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
10008: newsubcomm = PETSC_TRUE;
10009: PetscSubcommDestroy(&psubcomm);
10010: }
10012: /* get isrow, iscol and a local sequential matrix matseq[0] */
10013: if (reuse == MAT_INITIAL_MATRIX) {
10014: mloc_sub = PETSC_DECIDE;
10015: nloc_sub = PETSC_DECIDE;
10016: if (bs < 1) {
10017: PetscSplitOwnership(subcomm,&mloc_sub,&M);
10018: PetscSplitOwnership(subcomm,&nloc_sub,&N);
10019: } else {
10020: PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
10021: PetscSplitOwnershipBlock(subcomm,bs,&nloc_sub,&N);
10022: }
10023: MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
10024: rstart = rend - mloc_sub;
10025: ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
10026: ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
10027: } else { /* reuse == MAT_REUSE_MATRIX */
10028: if (*matredundant == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10029: /* retrieve subcomm */
10030: PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
10031: redund = (*matredundant)->redundant;
10032: isrow = redund->isrow;
10033: iscol = redund->iscol;
10034: matseq = redund->matseq;
10035: }
10036: MatCreateSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
10038: /* get matredundant over subcomm */
10039: if (reuse == MAT_INITIAL_MATRIX) {
10040: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],nloc_sub,reuse,matredundant);
10042: /* create a supporting struct and attach it to C for reuse */
10043: PetscNewLog(*matredundant,&redund);
10044: (*matredundant)->redundant = redund;
10045: redund->isrow = isrow;
10046: redund->iscol = iscol;
10047: redund->matseq = matseq;
10048: if (newsubcomm) {
10049: redund->subcomm = subcomm;
10050: } else {
10051: redund->subcomm = MPI_COMM_NULL;
10052: }
10053: } else {
10054: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
10055: }
10056: PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10057: return(0);
10058: }
10060: /*@C
10061: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10062: a given 'mat' object. Each submatrix can span multiple procs.
10064: Collective on Mat
10066: Input Parameters:
10067: + mat - the matrix
10068: . subcomm - the subcommunicator obtained by com_split(comm)
10069: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10071: Output Parameter:
10072: . subMat - 'parallel submatrices each spans a given subcomm
10074: Notes:
10075: The submatrix partition across processors is dictated by 'subComm' a
10076: communicator obtained by com_split(comm). The comm_split
10077: is not restriced to be grouped with consecutive original ranks.
10079: Due the comm_split() usage, the parallel layout of the submatrices
10080: map directly to the layout of the original matrix [wrt the local
10081: row,col partitioning]. So the original 'DiagonalMat' naturally maps
10082: into the 'DiagonalMat' of the subMat, hence it is used directly from
10083: the subMat. However the offDiagMat looses some columns - and this is
10084: reconstructed with MatSetValues()
10086: Level: advanced
10088: Concepts: subcommunicator
10089: Concepts: submatrices
10091: .seealso: MatCreateSubMatrices()
10092: @*/
10093: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10094: {
10096: PetscMPIInt commsize,subCommSize;
10099: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10100: MPI_Comm_size(subComm,&subCommSize);
10101: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10103: if (scall == MAT_REUSE_MATRIX && *subMat == mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10104: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10105: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10106: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10107: return(0);
10108: }
10110: /*@
10111: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10113: Not Collective
10115: Input Arguments:
10116: mat - matrix to extract local submatrix from
10117: isrow - local row indices for submatrix
10118: iscol - local column indices for submatrix
10120: Output Arguments:
10121: submat - the submatrix
10123: Level: intermediate
10125: Notes:
10126: The submat should be returned with MatRestoreLocalSubMatrix().
10128: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
10129: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10131: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
10132: MatSetValuesBlockedLocal() will also be implemented.
10134: The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10135: matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10137: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10138: @*/
10139: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10140: {
10149: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10151: if (mat->ops->getlocalsubmatrix) {
10152: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10153: } else {
10154: MatCreateLocalRef(mat,isrow,iscol,submat);
10155: }
10156: return(0);
10157: }
10159: /*@
10160: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10162: Not Collective
10164: Input Arguments:
10165: mat - matrix to extract local submatrix from
10166: isrow - local row indices for submatrix
10167: iscol - local column indices for submatrix
10168: submat - the submatrix
10170: Level: intermediate
10172: .seealso: MatGetLocalSubMatrix()
10173: @*/
10174: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10175: {
10184: if (*submat) {
10186: }
10188: if (mat->ops->restorelocalsubmatrix) {
10189: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10190: } else {
10191: MatDestroy(submat);
10192: }
10193: *submat = NULL;
10194: return(0);
10195: }
10197: /* --------------------------------------------------------*/
10198: /*@
10199: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no diagonal entry in the matrix
10201: Collective on Mat
10203: Input Parameter:
10204: . mat - the matrix
10206: Output Parameter:
10207: . is - if any rows have zero diagonals this contains the list of them
10209: Level: developer
10211: Concepts: matrix-vector product
10213: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10214: @*/
10215: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10216: {
10222: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10223: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10225: if (!mat->ops->findzerodiagonals) {
10226: Vec diag;
10227: const PetscScalar *a;
10228: PetscInt *rows;
10229: PetscInt rStart, rEnd, r, nrow = 0;
10231: MatCreateVecs(mat, &diag, NULL);
10232: MatGetDiagonal(mat, diag);
10233: MatGetOwnershipRange(mat, &rStart, &rEnd);
10234: VecGetArrayRead(diag, &a);
10235: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10236: PetscMalloc1(nrow, &rows);
10237: nrow = 0;
10238: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10239: VecRestoreArrayRead(diag, &a);
10240: VecDestroy(&diag);
10241: ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10242: } else {
10243: (*mat->ops->findzerodiagonals)(mat, is);
10244: }
10245: return(0);
10246: }
10248: /*@
10249: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10251: Collective on Mat
10253: Input Parameter:
10254: . mat - the matrix
10256: Output Parameter:
10257: . is - contains the list of rows with off block diagonal entries
10259: Level: developer
10261: Concepts: matrix-vector product
10263: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10264: @*/
10265: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10266: {
10272: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10273: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10275: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10276: (*mat->ops->findoffblockdiagonalentries)(mat,is);
10277: return(0);
10278: }
10280: /*@C
10281: MatInvertBlockDiagonal - Inverts the block diagonal entries.
10283: Collective on Mat
10285: Input Parameters:
10286: . mat - the matrix
10288: Output Parameters:
10289: . values - the block inverses in column major order (FORTRAN-like)
10291: Note:
10292: This routine is not available from Fortran.
10294: Level: advanced
10295: @*/
10296: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10297: {
10302: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10303: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10304: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10305: (*mat->ops->invertblockdiagonal)(mat,values);
10306: return(0);
10307: }
10309: /*@C
10310: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10311: via MatTransposeColoringCreate().
10313: Collective on MatTransposeColoring
10315: Input Parameter:
10316: . c - coloring context
10318: Level: intermediate
10320: .seealso: MatTransposeColoringCreate()
10321: @*/
10322: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10323: {
10324: PetscErrorCode ierr;
10325: MatTransposeColoring matcolor=*c;
10328: if (!matcolor) return(0);
10329: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
10331: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10332: PetscFree(matcolor->rows);
10333: PetscFree(matcolor->den2sp);
10334: PetscFree(matcolor->colorforcol);
10335: PetscFree(matcolor->columns);
10336: if (matcolor->brows>0) {
10337: PetscFree(matcolor->lstart);
10338: }
10339: PetscHeaderDestroy(c);
10340: return(0);
10341: }
10343: /*@C
10344: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10345: a MatTransposeColoring context has been created, computes a dense B^T by Apply
10346: MatTransposeColoring to sparse B.
10348: Collective on MatTransposeColoring
10350: Input Parameters:
10351: + B - sparse matrix B
10352: . Btdense - symbolic dense matrix B^T
10353: - coloring - coloring context created with MatTransposeColoringCreate()
10355: Output Parameter:
10356: . Btdense - dense matrix B^T
10358: Level: advanced
10360: Notes: These are used internally for some implementations of MatRARt()
10362: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplyDenToSp()
10364: .keywords: coloring
10365: @*/
10366: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10367: {
10375: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10376: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10377: return(0);
10378: }
10380: /*@C
10381: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10382: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10383: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10384: Csp from Cden.
10386: Collective on MatTransposeColoring
10388: Input Parameters:
10389: + coloring - coloring context created with MatTransposeColoringCreate()
10390: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
10392: Output Parameter:
10393: . Csp - sparse matrix
10395: Level: advanced
10397: Notes: These are used internally for some implementations of MatRARt()
10399: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10401: .keywords: coloring
10402: @*/
10403: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10404: {
10412: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10413: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10414: return(0);
10415: }
10417: /*@C
10418: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10420: Collective on Mat
10422: Input Parameters:
10423: + mat - the matrix product C
10424: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10426: Output Parameter:
10427: . color - the new coloring context
10429: Level: intermediate
10431: .seealso: MatTransposeColoringDestroy(), MatTransColoringApplySpToDen(),
10432: MatTransColoringApplyDenToSp()
10433: @*/
10434: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10435: {
10436: MatTransposeColoring c;
10437: MPI_Comm comm;
10438: PetscErrorCode ierr;
10441: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10442: PetscObjectGetComm((PetscObject)mat,&comm);
10443: PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10445: c->ctype = iscoloring->ctype;
10446: if (mat->ops->transposecoloringcreate) {
10447: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10448: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10450: *color = c;
10451: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10452: return(0);
10453: }
10455: /*@
10456: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10457: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10458: same, otherwise it will be larger
10460: Not Collective
10462: Input Parameter:
10463: . A - the matrix
10465: Output Parameter:
10466: . state - the current state
10468: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10469: different matrices
10471: Level: intermediate
10473: @*/
10474: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10475: {
10478: *state = mat->nonzerostate;
10479: return(0);
10480: }
10482: /*@
10483: MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10484: matrices from each processor
10486: Collective on MPI_Comm
10488: Input Parameters:
10489: + comm - the communicators the parallel matrix will live on
10490: . seqmat - the input sequential matrices
10491: . n - number of local columns (or PETSC_DECIDE)
10492: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10494: Output Parameter:
10495: . mpimat - the parallel matrix generated
10497: Level: advanced
10499: Notes: The number of columns of the matrix in EACH processor MUST be the same.
10501: @*/
10502: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10503: {
10507: if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10508: if (reuse == MAT_REUSE_MATRIX && seqmat == *mpimat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"MAT_REUSE_MATRIX means reuse the matrix passed in as the final argument, not the original matrix");
10510: PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10511: (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10512: PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10513: return(0);
10514: }
10516: /*@
10517: MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10518: ranks' ownership ranges.
10520: Collective on A
10522: Input Parameters:
10523: + A - the matrix to create subdomains from
10524: - N - requested number of subdomains
10527: Output Parameters:
10528: + n - number of subdomains resulting on this rank
10529: - iss - IS list with indices of subdomains on this rank
10531: Level: advanced
10533: Notes: number of subdomains must be smaller than the communicator size
10534: @*/
10535: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10536: {
10537: MPI_Comm comm,subcomm;
10538: PetscMPIInt size,rank,color;
10539: PetscInt rstart,rend,k;
10540: PetscErrorCode ierr;
10543: PetscObjectGetComm((PetscObject)A,&comm);
10544: MPI_Comm_size(comm,&size);
10545: MPI_Comm_rank(comm,&rank);
10546: if (N < 1 || N >= (PetscInt)size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"number of subdomains must be > 0 and < %D, got N = %D",size,N);
10547: *n = 1;
10548: k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10549: color = rank/k;
10550: MPI_Comm_split(comm,color,rank,&subcomm);
10551: PetscMalloc1(1,iss);
10552: MatGetOwnershipRange(A,&rstart,&rend);
10553: ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10554: MPI_Comm_free(&subcomm);
10555: return(0);
10556: }
10558: /*@
10559: MatGalerkin - Constructs the coarse grid problem via Galerkin projection.
10561: If the interpolation and restriction operators are the same, uses MatPtAP.
10562: If they are not the same, use MatMatMatMult.
10564: Once the coarse grid problem is constructed, correct for interpolation operators
10565: that are not of full rank, which can legitimately happen in the case of non-nested
10566: geometric multigrid.
10568: Input Parameters:
10569: + restrct - restriction operator
10570: . dA - fine grid matrix
10571: . interpolate - interpolation operator
10572: . reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10573: - fill - expected fill, use PETSC_DEFAULT if you do not have a good estimate
10575: Output Parameters:
10576: . A - the Galerkin coarse matrix
10578: Options Database Key:
10579: . -pc_mg_galerkin <both,pmat,mat,none>
10581: Level: developer
10583: .keywords: MG, multigrid, Galerkin
10585: .seealso: MatPtAP(), MatMatMatMult()
10586: @*/
10587: PetscErrorCode MatGalerkin(Mat restrct, Mat dA, Mat interpolate, MatReuse reuse, PetscReal fill, Mat *A)
10588: {
10590: IS zerorows;
10591: Vec diag;
10594: if (reuse == MAT_INPLACE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Inplace product not supported");
10595: /* Construct the coarse grid matrix */
10596: if (interpolate == restrct) {
10597: MatPtAP(dA,interpolate,reuse,fill,A);
10598: } else {
10599: MatMatMatMult(restrct,dA,interpolate,reuse,fill,A);
10600: }
10602: /* If the interpolation matrix is not of full rank, A will have zero rows.
10603: This can legitimately happen in the case of non-nested geometric multigrid.
10604: In that event, we set the rows of the matrix to the rows of the identity,
10605: ignoring the equations (as the RHS will also be zero). */
10607: MatFindZeroRows(*A, &zerorows);
10609: if (zerorows != NULL) { /* if there are any zero rows */
10610: MatCreateVecs(*A, &diag, NULL);
10611: MatGetDiagonal(*A, diag);
10612: VecISSet(diag, zerorows, 1.0);
10613: MatDiagonalSet(*A, diag, INSERT_VALUES);
10614: VecDestroy(&diag);
10615: ISDestroy(&zerorows);
10616: }
10617: return(0);
10618: }