Actual source code: matrix.c
petsc-3.7.3 2016-08-01
2: /*
3: This is where the abstract matrix operations are defined
4: */
6: #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc/private/vecimpl.h>
8: #include <petsc/private/isimpl.h>
10: /* Logging support */
11: PetscClassId MAT_CLASSID;
12: PetscClassId MAT_COLORING_CLASSID;
13: PetscClassId MAT_FDCOLORING_CLASSID;
14: PetscClassId MAT_TRANSPOSECOLORING_CLASSID;
16: PetscLogEvent MAT_Mult, MAT_Mults, MAT_MultConstrained, MAT_MultAdd, MAT_MultTranspose;
17: PetscLogEvent MAT_MultTransposeConstrained, MAT_MultTransposeAdd, MAT_Solve, MAT_Solves, MAT_SolveAdd, MAT_SolveTranspose, MAT_MatSolve;
18: PetscLogEvent MAT_SolveTransposeAdd, MAT_SOR, MAT_ForwardSolve, MAT_BackwardSolve, MAT_LUFactor, MAT_LUFactorSymbolic;
19: PetscLogEvent MAT_LUFactorNumeric, MAT_CholeskyFactor, MAT_CholeskyFactorSymbolic, MAT_CholeskyFactorNumeric, MAT_ILUFactor;
20: PetscLogEvent MAT_ILUFactorSymbolic, MAT_ICCFactorSymbolic, MAT_Copy, MAT_Convert, MAT_Scale, MAT_AssemblyBegin;
21: PetscLogEvent MAT_AssemblyEnd, MAT_SetValues, MAT_GetValues, MAT_GetRow, MAT_GetRowIJ, MAT_GetSubMatrices, MAT_GetOrdering, MAT_RedundantMat, MAT_GetSeqNonzeroStructure;
22: PetscLogEvent MAT_IncreaseOverlap, MAT_Partitioning, MAT_Coarsen, MAT_ZeroEntries, MAT_Load, MAT_View, MAT_AXPY, MAT_FDColoringCreate;
23: PetscLogEvent MAT_FDColoringSetUp, MAT_FDColoringApply,MAT_Transpose,MAT_FDColoringFunction, MAT_GetSubMatrix;
24: PetscLogEvent MAT_TransposeColoringCreate;
25: PetscLogEvent MAT_MatMult, MAT_MatMultSymbolic, MAT_MatMultNumeric;
26: PetscLogEvent MAT_PtAP, MAT_PtAPSymbolic, MAT_PtAPNumeric,MAT_RARt, MAT_RARtSymbolic, MAT_RARtNumeric;
27: PetscLogEvent MAT_MatTransposeMult, MAT_MatTransposeMultSymbolic, MAT_MatTransposeMultNumeric;
28: PetscLogEvent MAT_TransposeMatMult, MAT_TransposeMatMultSymbolic, MAT_TransposeMatMultNumeric;
29: PetscLogEvent MAT_MatMatMult, MAT_MatMatMultSymbolic, MAT_MatMatMultNumeric;
30: PetscLogEvent MAT_MultHermitianTranspose,MAT_MultHermitianTransposeAdd;
31: PetscLogEvent MAT_Getsymtranspose, MAT_Getsymtransreduced, MAT_Transpose_SeqAIJ, MAT_GetBrowsOfAcols;
32: PetscLogEvent MAT_GetBrowsOfAocols, MAT_Getlocalmat, MAT_Getlocalmatcondensed, MAT_Seqstompi, MAT_Seqstompinum, MAT_Seqstompisym;
33: PetscLogEvent MAT_Applypapt, MAT_Applypapt_numeric, MAT_Applypapt_symbolic, MAT_GetSequentialNonzeroStructure;
34: PetscLogEvent MAT_GetMultiProcBlock;
35: PetscLogEvent MAT_CUSPCopyToGPU, MAT_CUSPARSECopyToGPU, MAT_SetValuesBatch, MAT_SetValuesBatchI, MAT_SetValuesBatchII, MAT_SetValuesBatchIII, MAT_SetValuesBatchIV;
36: PetscLogEvent MAT_ViennaCLCopyToGPU;
37: PetscLogEvent MAT_Merge,MAT_Residual;
38: PetscLogEvent Mat_Coloring_Apply,Mat_Coloring_Comm,Mat_Coloring_Local,Mat_Coloring_ISCreate,Mat_Coloring_SetUp,Mat_Coloring_Weights;
40: const char *const MatFactorTypes[] = {"NONE","LU","CHOLESKY","ILU","ICC","ILUDT","MatFactorType","MAT_FACTOR_",0};
44: /*@
45: MatSetRandom - Sets all components of a matrix to random numbers. For sparse matrices that have been preallocated it randomly selects appropriate locations
47: Logically Collective on Vec
49: Input Parameters:
50: + x - the vector
51: - rctx - the random number context, formed by PetscRandomCreate(), or NULL and
52: it will create one internally.
54: Output Parameter:
55: . x - the vector
57: Example of Usage:
58: .vb
59: PetscRandomCreate(PETSC_COMM_WORLD,&rctx);
60: VecSetRandom(x,rctx);
61: PetscRandomDestroy(rctx);
62: .ve
64: Level: intermediate
66: Concepts: vector^setting to random
67: Concepts: random^vector
69: .seealso: MatZeroEntries(), MatSetValues(), PetscRandomCreate(), PetscRandomDestroy()
70: @*/
71: PetscErrorCode MatSetRandom(Mat x,PetscRandom rctx)
72: {
74: PetscRandom randObj = NULL;
81: if (!rctx) {
82: MPI_Comm comm;
83: PetscObjectGetComm((PetscObject)x,&comm);
84: PetscRandomCreate(comm,&randObj);
85: PetscRandomSetFromOptions(randObj);
86: rctx = randObj;
87: }
89: PetscLogEventBegin(VEC_SetRandom,x,rctx,0,0);
90: (*x->ops->setrandom)(x,rctx);
91: PetscLogEventEnd(VEC_SetRandom,x,rctx,0,0);
93: x->assembled = PETSC_TRUE;
94: PetscRandomDestroy(&randObj);
95: return(0);
96: }
101: /*@
102: MatFindNonzeroRows - Locate all rows that are not completely zero in the matrix
104: Input Parameter:
105: . A - the matrix
107: Output Parameter:
108: . keptrows - the rows that are not completely zero
110: Level: intermediate
112: @*/
113: PetscErrorCode MatFindNonzeroRows(Mat mat,IS *keptrows)
114: {
119: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
120: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
121: if (!mat->ops->findnonzerorows) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not coded for this matrix type");
122: (*mat->ops->findnonzerorows)(mat,keptrows);
123: return(0);
124: }
128: /*@
129: MatGetDiagonalBlock - Returns the part of the matrix associated with the on-process coupling
131: Not Collective
133: Input Parameters:
134: . A - the matrix
136: Output Parameters:
137: . a - the diagonal part (which is a SEQUENTIAL matrix)
139: Notes: see the manual page for MatCreateAIJ() for more information on the "diagonal part" of the matrix.
140: Use caution, as the reference count on the returned matrix is not incremented and it is used as
141: part of the containing MPI Mat's normal operation.
143: Level: advanced
145: @*/
146: PetscErrorCode MatGetDiagonalBlock(Mat A,Mat *a)
147: {
148: PetscErrorCode ierr,(*f)(Mat,Mat*);
149: PetscMPIInt size;
155: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
156: MPI_Comm_size(PetscObjectComm((PetscObject)A),&size);
157: PetscObjectQueryFunction((PetscObject)A,"MatGetDiagonalBlock_C",&f);
158: if (f) {
159: (*f)(A,a);
160: return(0);
161: } else if (size == 1) {
162: *a = A;
163: } else {
164: MatType mattype;
165: MatGetType(A,&mattype);
166: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix type %s does not support getting diagonal block",mattype);
167: }
168: return(0);
169: }
173: /*@
174: MatGetTrace - Gets the trace of a matrix. The sum of the diagonal entries.
176: Collective on Mat
178: Input Parameters:
179: . mat - the matrix
181: Output Parameter:
182: . trace - the sum of the diagonal entries
184: Level: advanced
186: @*/
187: PetscErrorCode MatGetTrace(Mat mat,PetscScalar *trace)
188: {
190: Vec diag;
193: MatCreateVecs(mat,&diag,NULL);
194: MatGetDiagonal(mat,diag);
195: VecSum(diag,trace);
196: VecDestroy(&diag);
197: return(0);
198: }
202: /*@
203: MatRealPart - Zeros out the imaginary part of the matrix
205: Logically Collective on Mat
207: Input Parameters:
208: . mat - the matrix
210: Level: advanced
213: .seealso: MatImaginaryPart()
214: @*/
215: PetscErrorCode MatRealPart(Mat mat)
216: {
222: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
223: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
224: if (!mat->ops->realpart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
225: MatCheckPreallocated(mat,1);
226: (*mat->ops->realpart)(mat);
227: #if defined(PETSC_HAVE_CUSP)
228: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
229: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
230: }
231: #elif defined(PETSC_HAVE_VIENNACL)
232: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
233: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
234: }
235: #elif defined(PETSC_HAVE_VECCUDA)
236: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
237: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
238: }
239: #endif
240: return(0);
241: }
245: /*@C
246: MatGetGhosts - Get the global index of all ghost nodes defined by the sparse matrix
248: Collective on Mat
250: Input Parameter:
251: . mat - the matrix
253: Output Parameters:
254: + nghosts - number of ghosts (note for BAIJ matrices there is one ghost for each block)
255: - ghosts - the global indices of the ghost points
257: Notes: the nghosts and ghosts are suitable to pass into VecCreateGhost()
259: Level: advanced
261: @*/
262: PetscErrorCode MatGetGhosts(Mat mat,PetscInt *nghosts,const PetscInt *ghosts[])
263: {
269: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
270: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
271: if (!mat->ops->getghosts) {
272: if (nghosts) *nghosts = 0;
273: if (ghosts) *ghosts = 0;
274: } else {
275: (*mat->ops->getghosts)(mat,nghosts,ghosts);
276: }
277: return(0);
278: }
283: /*@
284: MatImaginaryPart - Moves the imaginary part of the matrix to the real part and zeros the imaginary part
286: Logically Collective on Mat
288: Input Parameters:
289: . mat - the matrix
291: Level: advanced
294: .seealso: MatRealPart()
295: @*/
296: PetscErrorCode MatImaginaryPart(Mat mat)
297: {
303: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
304: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
305: if (!mat->ops->imaginarypart) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
306: MatCheckPreallocated(mat,1);
307: (*mat->ops->imaginarypart)(mat);
308: #if defined(PETSC_HAVE_CUSP)
309: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
310: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
311: }
312: #elif defined(PETSC_HAVE_VIENNACL)
313: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
314: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
315: }
316: #elif defined(PETSC_HAVE_VECCUDA)
317: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
318: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
319: }
320: #endif
321: return(0);
322: }
326: /*@
327: MatMissingDiagonal - Determine if sparse matrix is missing a diagonal entry (or block entry for BAIJ matrices)
329: Collective on Mat
331: Input Parameter:
332: . mat - the matrix
334: Output Parameters:
335: + missing - is any diagonal missing
336: - dd - first diagonal entry that is missing (optional)
338: Level: advanced
341: .seealso: MatRealPart()
342: @*/
343: PetscErrorCode MatMissingDiagonal(Mat mat,PetscBool *missing,PetscInt *dd)
344: {
350: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
351: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
352: if (!mat->ops->missingdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
353: (*mat->ops->missingdiagonal)(mat,missing,dd);
354: return(0);
355: }
359: /*@C
360: MatGetRow - Gets a row of a matrix. You MUST call MatRestoreRow()
361: for each row that you get to ensure that your application does
362: not bleed memory.
364: Not Collective
366: Input Parameters:
367: + mat - the matrix
368: - row - the row to get
370: Output Parameters:
371: + ncols - if not NULL, the number of nonzeros in the row
372: . cols - if not NULL, the column numbers
373: - vals - if not NULL, the values
375: Notes:
376: This routine is provided for people who need to have direct access
377: to the structure of a matrix. We hope that we provide enough
378: high-level matrix routines that few users will need it.
380: MatGetRow() always returns 0-based column indices, regardless of
381: whether the internal representation is 0-based (default) or 1-based.
383: For better efficiency, set cols and/or vals to NULL if you do
384: not wish to extract these quantities.
386: The user can only examine the values extracted with MatGetRow();
387: the values cannot be altered. To change the matrix entries, one
388: must use MatSetValues().
390: You can only have one call to MatGetRow() outstanding for a particular
391: matrix at a time, per processor. MatGetRow() can only obtain rows
392: associated with the given processor, it cannot get rows from the
393: other processors; for that we suggest using MatGetSubMatrices(), then
394: MatGetRow() on the submatrix. The row indix passed to MatGetRows()
395: is in the global number of rows.
397: Fortran Notes:
398: The calling sequence from Fortran is
399: .vb
400: MatGetRow(matrix,row,ncols,cols,values,ierr)
401: Mat matrix (input)
402: integer row (input)
403: integer ncols (output)
404: integer cols(maxcols) (output)
405: double precision (or double complex) values(maxcols) output
406: .ve
407: where maxcols >= maximum nonzeros in any row of the matrix.
410: Caution:
411: Do not try to change the contents of the output arrays (cols and vals).
412: In some cases, this may corrupt the matrix.
414: Level: advanced
416: Concepts: matrices^row access
418: .seealso: MatRestoreRow(), MatSetValues(), MatGetValues(), MatGetSubMatrices(), MatGetDiagonal()
419: @*/
420: PetscErrorCode MatGetRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
421: {
423: PetscInt incols;
428: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
429: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
430: if (!mat->ops->getrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
431: MatCheckPreallocated(mat,1);
432: PetscLogEventBegin(MAT_GetRow,mat,0,0,0);
433: (*mat->ops->getrow)(mat,row,&incols,(PetscInt**)cols,(PetscScalar**)vals);
434: if (ncols) *ncols = incols;
435: PetscLogEventEnd(MAT_GetRow,mat,0,0,0);
436: return(0);
437: }
441: /*@
442: MatConjugate - replaces the matrix values with their complex conjugates
444: Logically Collective on Mat
446: Input Parameters:
447: . mat - the matrix
449: Level: advanced
451: .seealso: VecConjugate()
452: @*/
453: PetscErrorCode MatConjugate(Mat mat)
454: {
455: #if defined(PETSC_USE_COMPLEX)
460: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
461: 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");
462: (*mat->ops->conjugate)(mat);
463: #if defined(PETSC_HAVE_CUSP)
464: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
465: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
466: }
467: #elif defined(PETSC_HAVE_VIENNACL)
468: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
469: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
470: }
471: #elif defined(PETSC_HAVE_VECCUDA)
472: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
473: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
474: }
475: #endif
476: return(0);
477: #else
478: return 0;
479: #endif
480: }
484: /*@C
485: MatRestoreRow - Frees any temporary space allocated by MatGetRow().
487: Not Collective
489: Input Parameters:
490: + mat - the matrix
491: . row - the row to get
492: . ncols, cols - the number of nonzeros and their columns
493: - vals - if nonzero the column values
495: Notes:
496: This routine should be called after you have finished examining the entries.
498: This routine zeros out ncols, cols, and vals. This is to prevent accidental
499: us of the array after it has been restored. If you pass NULL, it will
500: not zero the pointers. Use of cols or vals after MatRestoreRow is invalid.
502: Fortran Notes:
503: The calling sequence from Fortran is
504: .vb
505: MatRestoreRow(matrix,row,ncols,cols,values,ierr)
506: Mat matrix (input)
507: integer row (input)
508: integer ncols (output)
509: integer cols(maxcols) (output)
510: double precision (or double complex) values(maxcols) output
511: .ve
512: Where maxcols >= maximum nonzeros in any row of the matrix.
514: In Fortran MatRestoreRow() MUST be called after MatGetRow()
515: before another call to MatGetRow() can be made.
517: Level: advanced
519: .seealso: MatGetRow()
520: @*/
521: PetscErrorCode MatRestoreRow(Mat mat,PetscInt row,PetscInt *ncols,const PetscInt *cols[],const PetscScalar *vals[])
522: {
528: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
529: if (!mat->ops->restorerow) return(0);
530: (*mat->ops->restorerow)(mat,row,ncols,(PetscInt **)cols,(PetscScalar **)vals);
531: if (ncols) *ncols = 0;
532: if (cols) *cols = NULL;
533: if (vals) *vals = NULL;
534: return(0);
535: }
539: /*@
540: MatGetRowUpperTriangular - Sets a flag to enable calls to MatGetRow() for matrix in MATSBAIJ format.
541: You should call MatRestoreRowUpperTriangular() after calling MatGetRow/MatRestoreRow() to disable the flag.
543: Not Collective
545: Input Parameters:
546: + mat - the matrix
548: Notes:
549: 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.
551: Level: advanced
553: Concepts: matrices^row access
555: .seealso: MatRestoreRowRowUpperTriangular()
556: @*/
557: PetscErrorCode MatGetRowUpperTriangular(Mat mat)
558: {
564: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
565: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
566: if (!mat->ops->getrowuppertriangular) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
567: MatCheckPreallocated(mat,1);
568: (*mat->ops->getrowuppertriangular)(mat);
569: return(0);
570: }
574: /*@
575: MatRestoreRowUpperTriangular - Disable calls to MatGetRow() for matrix in MATSBAIJ format.
577: Not Collective
579: Input Parameters:
580: + mat - the matrix
582: Notes:
583: This routine should be called after you have finished MatGetRow/MatRestoreRow().
586: Level: advanced
588: .seealso: MatGetRowUpperTriangular()
589: @*/
590: PetscErrorCode MatRestoreRowUpperTriangular(Mat mat)
591: {
596: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
597: if (!mat->ops->restorerowuppertriangular) return(0);
598: (*mat->ops->restorerowuppertriangular)(mat);
599: return(0);
600: }
604: /*@C
605: MatSetOptionsPrefix - Sets the prefix used for searching for all
606: Mat options in the database.
608: Logically Collective on Mat
610: Input Parameter:
611: + A - the Mat context
612: - prefix - the prefix to prepend to all option names
614: Notes:
615: A hyphen (-) must NOT be given at the beginning of the prefix name.
616: The first character of all runtime options is AUTOMATICALLY the hyphen.
618: Level: advanced
620: .keywords: Mat, set, options, prefix, database
622: .seealso: MatSetFromOptions()
623: @*/
624: PetscErrorCode MatSetOptionsPrefix(Mat A,const char prefix[])
625: {
630: PetscObjectSetOptionsPrefix((PetscObject)A,prefix);
631: return(0);
632: }
636: /*@C
637: MatAppendOptionsPrefix - Appends to the prefix used for searching for all
638: Mat options in the database.
640: Logically Collective on Mat
642: Input Parameters:
643: + A - the Mat context
644: - prefix - the prefix to prepend to all option names
646: Notes:
647: A hyphen (-) must NOT be given at the beginning of the prefix name.
648: The first character of all runtime options is AUTOMATICALLY the hyphen.
650: Level: advanced
652: .keywords: Mat, append, options, prefix, database
654: .seealso: MatGetOptionsPrefix()
655: @*/
656: PetscErrorCode MatAppendOptionsPrefix(Mat A,const char prefix[])
657: {
662: PetscObjectAppendOptionsPrefix((PetscObject)A,prefix);
663: return(0);
664: }
668: /*@C
669: MatGetOptionsPrefix - Sets the prefix used for searching for all
670: Mat options in the database.
672: Not Collective
674: Input Parameter:
675: . A - the Mat context
677: Output Parameter:
678: . prefix - pointer to the prefix string used
680: Notes: On the fortran side, the user should pass in a string 'prefix' of
681: sufficient length to hold the prefix.
683: Level: advanced
685: .keywords: Mat, get, options, prefix, database
687: .seealso: MatAppendOptionsPrefix()
688: @*/
689: PetscErrorCode MatGetOptionsPrefix(Mat A,const char *prefix[])
690: {
695: PetscObjectGetOptionsPrefix((PetscObject)A,prefix);
696: return(0);
697: }
701: /*@
702: MatSetUp - Sets up the internal matrix data structures for the later use.
704: Collective on Mat
706: Input Parameters:
707: . A - the Mat context
709: Notes:
710: If the user has not set preallocation for this matrix then a default preallocation that is likely to be inefficient is used.
712: If a suitable preallocation routine is used, this function does not need to be called.
714: See the Performance chapter of the PETSc users manual for how to preallocate matrices
716: Level: beginner
718: .keywords: Mat, setup
720: .seealso: MatCreate(), MatDestroy()
721: @*/
722: PetscErrorCode MatSetUp(Mat A)
723: {
724: PetscMPIInt size;
729: if (!((PetscObject)A)->type_name) {
730: MPI_Comm_size(PetscObjectComm((PetscObject)A), &size);
731: if (size == 1) {
732: MatSetType(A, MATSEQAIJ);
733: } else {
734: MatSetType(A, MATMPIAIJ);
735: }
736: }
737: if (!A->preallocated && A->ops->setup) {
738: PetscInfo(A,"Warning not preallocating matrix storage\n");
739: (*A->ops->setup)(A);
740: }
741: A->preallocated = PETSC_TRUE;
742: return(0);
743: }
745: #if defined(PETSC_HAVE_SAWS)
746: #include <petscviewersaws.h>
747: #endif
750: /*@C
751: MatView - Visualizes a matrix object.
753: Collective on Mat
755: Input Parameters:
756: + mat - the matrix
757: - viewer - visualization context
759: Notes:
760: The available visualization contexts include
761: + PETSC_VIEWER_STDOUT_SELF - for sequential matrices
762: . PETSC_VIEWER_STDOUT_WORLD - for parallel matrices created on PETSC_COMM_WORLD
763: . PETSC_VIEWER_STDOUT_(comm) - for matrices created on MPI communicator comm
764: - PETSC_VIEWER_DRAW_WORLD - graphical display of nonzero structure
766: The user can open alternative visualization contexts with
767: + PetscViewerASCIIOpen() - Outputs matrix to a specified file
768: . PetscViewerBinaryOpen() - Outputs matrix in binary to a
769: specified file; corresponding input uses MatLoad()
770: . PetscViewerDrawOpen() - Outputs nonzero matrix structure to
771: an X window display
772: - PetscViewerSocketOpen() - Outputs matrix to Socket viewer.
773: Currently only the sequential dense and AIJ
774: matrix types support the Socket viewer.
776: The user can call PetscViewerPushFormat() to specify the output
777: format of ASCII printed objects (when using PETSC_VIEWER_STDOUT_SELF,
778: PETSC_VIEWER_STDOUT_WORLD and PetscViewerASCIIOpen). Available formats include
779: + PETSC_VIEWER_DEFAULT - default, prints matrix contents
780: . PETSC_VIEWER_ASCII_MATLAB - prints matrix contents in Matlab format
781: . PETSC_VIEWER_ASCII_DENSE - prints entire matrix including zeros
782: . PETSC_VIEWER_ASCII_COMMON - prints matrix contents, using a sparse
783: format common among all matrix types
784: . PETSC_VIEWER_ASCII_IMPL - prints matrix contents, using an implementation-specific
785: format (which is in many cases the same as the default)
786: . PETSC_VIEWER_ASCII_INFO - prints basic information about the matrix
787: size and structure (not the matrix entries)
788: . PETSC_VIEWER_ASCII_INFO_DETAIL - prints more detailed information about
789: the matrix structure
791: Options Database Keys:
792: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
793: . -mat_view ::ascii_info_detail - Prints more detailed info
794: . -mat_view - Prints matrix in ASCII format
795: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
796: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
797: . -display <name> - Sets display name (default is host)
798: . -draw_pause <sec> - Sets number of seconds to pause after display
799: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (see Users-Manual: Chapter 11 Using MATLAB with PETSc for details)
800: . -viewer_socket_machine <machine> -
801: . -viewer_socket_port <port> -
802: . -mat_view binary - save matrix to file in binary format
803: - -viewer_binary_filename <name> -
804: Level: beginner
806: Notes: see the manual page for MatLoad() for the exact format of the binary file when the binary
807: viewer is used.
809: See share/petsc/matlab/PetscBinaryRead.m for a Matlab code that can read in the binary file when the binary
810: viewer is used.
812: One can use '-mat_view draw -draw_pause -1' to pause the graphical display of matrix nonzero structure.
813: And then use the following mouse functions:
814: left mouse: zoom in
815: middle mouse: zoom out
816: right mouse: continue with the simulation
818: Concepts: matrices^viewing
819: Concepts: matrices^plotting
820: Concepts: matrices^printing
822: .seealso: PetscViewerPushFormat(), PetscViewerASCIIOpen(), PetscViewerDrawOpen(),
823: PetscViewerSocketOpen(), PetscViewerBinaryOpen(), MatLoad()
824: @*/
825: PetscErrorCode MatView(Mat mat,PetscViewer viewer)
826: {
827: PetscErrorCode ierr;
828: PetscInt rows,cols,rbs,cbs;
829: PetscBool iascii,ibinary;
830: PetscViewerFormat format;
831: #if defined(PETSC_HAVE_SAWS)
832: PetscBool issaws;
833: #endif
838: if (!viewer) {
839: PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)mat),&viewer);
840: }
843: MatCheckPreallocated(mat,1);
844: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&ibinary);
845: if (ibinary) {
846: PetscBool mpiio;
847: PetscViewerBinaryGetUseMPIIO(viewer,&mpiio);
848: if (mpiio) SETERRQ(PetscObjectComm((PetscObject)viewer),PETSC_ERR_SUP,"PETSc matrix viewers do not support using MPI-IO, turn off that flag");
849: }
851: PetscLogEventBegin(MAT_View,mat,viewer,0,0);
852: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
853: PetscViewerGetFormat(viewer,&format);
854: if ((!iascii || (format != PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL)) && mat->factortype) {
855: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"No viewers for factored matrix except ASCII info or info_detailed");
856: }
858: #if defined(PETSC_HAVE_SAWS)
859: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws);
860: #endif
861: if (iascii) {
862: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
863: PetscObjectPrintClassNamePrefixType((PetscObject)mat,viewer);
864: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
865: PetscViewerASCIIPushTab(viewer);
866: MatGetSize(mat,&rows,&cols);
867: MatGetBlockSizes(mat,&rbs,&cbs);
868: if (rbs != 1 || cbs != 1) {
869: if (rbs != cbs) {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, rbs=%D, cbs = %D\n",rows,cols,rbs,cbs);}
870: else {PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D, bs=%D\n",rows,cols,rbs);}
871: } else {
872: PetscViewerASCIIPrintf(viewer,"rows=%D, cols=%D\n",rows,cols);
873: }
874: if (mat->factortype) {
875: const MatSolverPackage solver;
876: MatFactorGetSolverPackage(mat,&solver);
877: PetscViewerASCIIPrintf(viewer,"package used to perform factorization: %s\n",solver);
878: }
879: if (mat->ops->getinfo) {
880: MatInfo info;
881: MatGetInfo(mat,MAT_GLOBAL_SUM,&info);
882: PetscViewerASCIIPrintf(viewer,"total: nonzeros=%.f, allocated nonzeros=%.f\n",info.nz_used,info.nz_allocated);
883: PetscViewerASCIIPrintf(viewer,"total number of mallocs used during MatSetValues calls =%D\n",(PetscInt)info.mallocs);
884: }
885: if (mat->nullsp) {PetscViewerASCIIPrintf(viewer," has attached null space\n");}
886: if (mat->nearnullsp) {PetscViewerASCIIPrintf(viewer," has attached near null space\n");}
887: }
888: #if defined(PETSC_HAVE_SAWS)
889: } else if (issaws) {
890: PetscMPIInt rank;
892: PetscObjectName((PetscObject)mat);
893: MPI_Comm_rank(PETSC_COMM_WORLD,&rank);
894: if (!((PetscObject)mat)->amsmem && !rank) {
895: PetscObjectViewSAWs((PetscObject)mat,viewer);
896: }
897: #endif
898: }
899: if (mat->ops->view) {
900: PetscViewerASCIIPushTab(viewer);
901: (*mat->ops->view)(mat,viewer);
902: PetscViewerASCIIPopTab(viewer);
903: }
904: if (iascii) {
905: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ORDER,"Must call MatAssemblyBegin/End() before viewing matrix");
906: PetscViewerGetFormat(viewer,&format);
907: if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
908: PetscViewerASCIIPopTab(viewer);
909: }
910: }
911: PetscLogEventEnd(MAT_View,mat,viewer,0,0);
912: return(0);
913: }
915: #if defined(PETSC_USE_DEBUG)
916: #include <../src/sys/totalview/tv_data_display.h>
917: PETSC_UNUSED static int TV_display_type(const struct _p_Mat *mat)
918: {
919: TV_add_row("Local rows", "int", &mat->rmap->n);
920: TV_add_row("Local columns", "int", &mat->cmap->n);
921: TV_add_row("Global rows", "int", &mat->rmap->N);
922: TV_add_row("Global columns", "int", &mat->cmap->N);
923: TV_add_row("Typename", TV_ascii_string_type, ((PetscObject)mat)->type_name);
924: return TV_format_OK;
925: }
926: #endif
930: /*@C
931: MatLoad - Loads a matrix that has been stored in binary format
932: with MatView(). The matrix format is determined from the options database.
933: Generates a parallel MPI matrix if the communicator has more than one
934: processor. The default matrix type is AIJ.
936: Collective on PetscViewer
938: Input Parameters:
939: + newmat - the newly loaded matrix, this needs to have been created with MatCreate()
940: or some related function before a call to MatLoad()
941: - viewer - binary file viewer, created with PetscViewerBinaryOpen()
943: Options Database Keys:
944: Used with block matrix formats (MATSEQBAIJ, ...) to specify
945: block size
946: . -matload_block_size <bs>
948: Level: beginner
950: Notes:
951: If the Mat type has not yet been given then MATAIJ is used, call MatSetFromOptions() on the
952: Mat before calling this routine if you wish to set it from the options database.
954: MatLoad() automatically loads into the options database any options
955: given in the file filename.info where filename is the name of the file
956: that was passed to the PetscViewerBinaryOpen(). The options in the info
957: file will be ignored if you use the -viewer_binary_skip_info option.
959: If the type or size of newmat is not set before a call to MatLoad, PETSc
960: sets the default matrix type AIJ and sets the local and global sizes.
961: If type and/or size is already set, then the same are used.
963: In parallel, each processor can load a subset of rows (or the
964: entire matrix). This routine is especially useful when a large
965: matrix is stored on disk and only part of it is desired on each
966: processor. For example, a parallel solver may access only some of
967: the rows from each processor. The algorithm used here reads
968: relatively small blocks of data rather than reading the entire
969: matrix and then subsetting it.
971: Notes for advanced users:
972: Most users should not need to know the details of the binary storage
973: format, since MatLoad() and MatView() completely hide these details.
974: But for anyone who's interested, the standard binary matrix storage
975: format is
977: $ int MAT_FILE_CLASSID
978: $ int number of rows
979: $ int number of columns
980: $ int total number of nonzeros
981: $ int *number nonzeros in each row
982: $ int *column indices of all nonzeros (starting index is zero)
983: $ PetscScalar *values of all nonzeros
985: PETSc automatically does the byte swapping for
986: machines that store the bytes reversed, e.g. DEC alpha, freebsd,
987: linux, Windows and the paragon; thus if you write your own binary
988: read/write routines you have to swap the bytes; see PetscBinaryRead()
989: and PetscBinaryWrite() to see how this may be done.
991: .keywords: matrix, load, binary, input
993: .seealso: PetscViewerBinaryOpen(), MatView(), VecLoad()
995: @*/
996: PetscErrorCode MatLoad(Mat newmat,PetscViewer viewer)
997: {
999: PetscBool isbinary,flg;
1004: PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);
1005: if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()");
1007: if (!((PetscObject)newmat)->type_name) {
1008: MatSetType(newmat,MATAIJ);
1009: }
1011: if (!newmat->ops->load) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatLoad is not supported for type");
1012: PetscLogEventBegin(MAT_Load,viewer,0,0,0);
1013: (*newmat->ops->load)(newmat,viewer);
1014: PetscLogEventEnd(MAT_Load,viewer,0,0,0);
1016: flg = PETSC_FALSE;
1017: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_symmetric",&flg,NULL);
1018: if (flg) {
1019: MatSetOption(newmat,MAT_SYMMETRIC,PETSC_TRUE);
1020: MatSetOption(newmat,MAT_SYMMETRY_ETERNAL,PETSC_TRUE);
1021: }
1022: flg = PETSC_FALSE;
1023: PetscOptionsGetBool(((PetscObject)newmat)->options,((PetscObject)newmat)->prefix,"-matload_spd",&flg,NULL);
1024: if (flg) {
1025: MatSetOption(newmat,MAT_SPD,PETSC_TRUE);
1026: }
1027: return(0);
1028: }
1032: PetscErrorCode MatDestroy_Redundant(Mat_Redundant **redundant)
1033: {
1035: Mat_Redundant *redund = *redundant;
1036: PetscInt i;
1039: if (redund){
1040: if (redund->matseq) { /* via MatGetSubMatrices() */
1041: ISDestroy(&redund->isrow);
1042: ISDestroy(&redund->iscol);
1043: MatDestroy(&redund->matseq[0]);
1044: PetscFree(redund->matseq);
1045: } else {
1046: PetscFree2(redund->send_rank,redund->recv_rank);
1047: PetscFree(redund->sbuf_j);
1048: PetscFree(redund->sbuf_a);
1049: for (i=0; i<redund->nrecvs; i++) {
1050: PetscFree(redund->rbuf_j[i]);
1051: PetscFree(redund->rbuf_a[i]);
1052: }
1053: PetscFree4(redund->sbuf_nz,redund->rbuf_nz,redund->rbuf_j,redund->rbuf_a);
1054: }
1056: if (redund->subcomm) {
1057: PetscCommDestroy(&redund->subcomm);
1058: }
1059: PetscFree(redund);
1060: }
1061: return(0);
1062: }
1066: /*@
1067: MatDestroy - Frees space taken by a matrix.
1069: Collective on Mat
1071: Input Parameter:
1072: . A - the matrix
1074: Level: beginner
1076: @*/
1077: PetscErrorCode MatDestroy(Mat *A)
1078: {
1082: if (!*A) return(0);
1084: if (--((PetscObject)(*A))->refct > 0) {*A = NULL; return(0);}
1086: /* if memory was published with SAWs then destroy it */
1087: PetscObjectSAWsViewOff((PetscObject)*A);
1088: if ((*A)->ops->destroy) {
1089: (*(*A)->ops->destroy)(*A);
1090: }
1092: PetscFree((*A)->solvertype);
1093: MatDestroy_Redundant(&(*A)->redundant);
1094: MatNullSpaceDestroy(&(*A)->nullsp);
1095: MatNullSpaceDestroy(&(*A)->transnullsp);
1096: MatNullSpaceDestroy(&(*A)->nearnullsp);
1097: PetscLayoutDestroy(&(*A)->rmap);
1098: PetscLayoutDestroy(&(*A)->cmap);
1099: PetscHeaderDestroy(A);
1100: return(0);
1101: }
1105: /*@
1106: MatSetValues - Inserts or adds a block of values into a matrix.
1107: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
1108: MUST be called after all calls to MatSetValues() have been completed.
1110: Not Collective
1112: Input Parameters:
1113: + mat - the matrix
1114: . v - a logically two-dimensional array of values
1115: . m, idxm - the number of rows and their global indices
1116: . n, idxn - the number of columns and their global indices
1117: - addv - either ADD_VALUES or INSERT_VALUES, where
1118: ADD_VALUES adds values to any existing entries, and
1119: INSERT_VALUES replaces existing entries with new values
1121: Notes:
1122: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1123: MatSetUp() before using this routine
1125: By default the values, v, are row-oriented. See MatSetOption() for other options.
1127: Calls to MatSetValues() with the INSERT_VALUES and ADD_VALUES
1128: options cannot be mixed without intervening calls to the assembly
1129: routines.
1131: MatSetValues() uses 0-based row and column numbers in Fortran
1132: as well as in C.
1134: Negative indices may be passed in idxm and idxn, these rows and columns are
1135: simply ignored. This allows easily inserting element stiffness matrices
1136: with homogeneous Dirchlet boundary conditions that you don't want represented
1137: in the matrix.
1139: Efficiency Alert:
1140: The routine MatSetValuesBlocked() may offer much better efficiency
1141: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1143: Level: beginner
1145: Concepts: matrices^putting entries in
1147: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1148: InsertMode, INSERT_VALUES, ADD_VALUES
1149: @*/
1150: PetscErrorCode MatSetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1151: {
1153: #if defined(PETSC_USE_DEBUG)
1154: PetscInt i,j;
1155: #endif
1160: if (!m || !n) return(0); /* no values to insert */
1164: MatCheckPreallocated(mat,1);
1165: if (mat->insertmode == NOT_SET_VALUES) {
1166: mat->insertmode = addv;
1167: }
1168: #if defined(PETSC_USE_DEBUG)
1169: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1170: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1171: if (!mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1173: for (i=0; i<m; i++) {
1174: for (j=0; j<n; j++) {
1175: if (mat->erroriffailure && PetscIsInfOrNanScalar(v[i*n+j]))
1176: #if defined(PETSC_USE_COMPLEX)
1177: 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]);
1178: #else
1179: SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_FP,"Inserting %g at matrix entry (%D,%D)",(double)v[i*n+j],idxm[i],idxn[j]);
1180: #endif
1181: }
1182: }
1183: #endif
1185: if (mat->assembled) {
1186: mat->was_assembled = PETSC_TRUE;
1187: mat->assembled = PETSC_FALSE;
1188: }
1189: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1190: (*mat->ops->setvalues)(mat,m,idxm,n,idxn,v,addv);
1191: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1192: #if defined(PETSC_HAVE_CUSP)
1193: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1194: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1195: }
1196: #elif defined(PETSC_HAVE_VIENNACL)
1197: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1198: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1199: }
1200: #elif defined(PETSC_HAVE_VECCUDA)
1201: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1202: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1203: }
1204: #endif
1205: return(0);
1206: }
1211: /*@
1212: MatSetValuesRowLocal - Inserts a row (block row for BAIJ matrices) of nonzero
1213: values into a matrix
1215: Not Collective
1217: Input Parameters:
1218: + mat - the matrix
1219: . row - the (block) row to set
1220: - v - a logically two-dimensional array of values
1222: Notes:
1223: By the values, v, are column-oriented (for the block version) and sorted
1225: All the nonzeros in the row must be provided
1227: The matrix must have previously had its column indices set
1229: The row must belong to this process
1231: Level: intermediate
1233: Concepts: matrices^putting entries in
1235: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1236: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues(), MatSetValuesRow(), MatSetLocalToGlobalMapping()
1237: @*/
1238: PetscErrorCode MatSetValuesRowLocal(Mat mat,PetscInt row,const PetscScalar v[])
1239: {
1241: PetscInt globalrow;
1247: ISLocalToGlobalMappingApply(mat->rmap->mapping,1,&row,&globalrow);
1248: MatSetValuesRow(mat,globalrow,v);
1249: #if defined(PETSC_HAVE_CUSP)
1250: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1251: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1252: }
1253: #elif defined(PETSC_HAVE_VIENNACL)
1254: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1255: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1256: }
1257: #elif defined(PETSC_HAVE_VECCUDA)
1258: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1259: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1260: }
1261: #endif
1262: return(0);
1263: }
1267: /*@
1268: MatSetValuesRow - Inserts a row (block row for BAIJ matrices) of nonzero
1269: values into a matrix
1271: Not Collective
1273: Input Parameters:
1274: + mat - the matrix
1275: . row - the (block) row to set
1276: - v - a logically two-dimensional array of values
1278: Notes:
1279: The values, v, are column-oriented for the block version.
1281: All the nonzeros in the row must be provided
1283: THE MATRIX MUSAT HAVE PREVIOUSLY HAD ITS COLUMN INDICES SET. IT IS RARE THAT THIS ROUTINE IS USED, usually MatSetValues() is used.
1285: The row must belong to this process
1287: Level: advanced
1289: Concepts: matrices^putting entries in
1291: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1292: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1293: @*/
1294: PetscErrorCode MatSetValuesRow(Mat mat,PetscInt row,const PetscScalar v[])
1295: {
1301: MatCheckPreallocated(mat,1);
1303: #if defined(PETSC_USE_DEBUG)
1304: if (mat->insertmode == ADD_VALUES) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add and insert values");
1305: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1306: #endif
1307: mat->insertmode = INSERT_VALUES;
1309: if (mat->assembled) {
1310: mat->was_assembled = PETSC_TRUE;
1311: mat->assembled = PETSC_FALSE;
1312: }
1313: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1314: if (!mat->ops->setvaluesrow) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1315: (*mat->ops->setvaluesrow)(mat,row,v);
1316: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1317: #if defined(PETSC_HAVE_CUSP)
1318: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1319: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1320: }
1321: #elif defined(PETSC_HAVE_VIENNACL)
1322: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1323: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1324: }
1325: #elif defined(PETSC_HAVE_VECCUDA)
1326: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1327: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1328: }
1329: #endif
1330: return(0);
1331: }
1335: /*@
1336: MatSetValuesStencil - Inserts or adds a block of values into a matrix.
1337: Using structured grid indexing
1339: Not Collective
1341: Input Parameters:
1342: + mat - the matrix
1343: . m - number of rows being entered
1344: . idxm - grid coordinates (and component number when dof > 1) for matrix rows being entered
1345: . n - number of columns being entered
1346: . idxn - grid coordinates (and component number when dof > 1) for matrix columns being entered
1347: . v - a logically two-dimensional array of values
1348: - addv - either ADD_VALUES or INSERT_VALUES, where
1349: ADD_VALUES adds values to any existing entries, and
1350: INSERT_VALUES replaces existing entries with new values
1352: Notes:
1353: By default the values, v, are row-oriented. See MatSetOption() for other options.
1355: Calls to MatSetValuesStencil() with the INSERT_VALUES and ADD_VALUES
1356: options cannot be mixed without intervening calls to the assembly
1357: routines.
1359: The grid coordinates are across the entire grid, not just the local portion
1361: MatSetValuesStencil() uses 0-based row and column numbers in Fortran
1362: as well as in C.
1364: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1366: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1367: or call MatSetLocalToGlobalMapping() and MatSetStencil() first.
1369: The columns and rows in the stencil passed in MUST be contained within the
1370: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1371: if you create a DMDA with an overlap of one grid level and on a particular process its first
1372: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1373: first i index you can use in your column and row indices in MatSetStencil() is 5.
1375: In Fortran idxm and idxn should be declared as
1376: $ MatStencil idxm(4,m),idxn(4,n)
1377: and the values inserted using
1378: $ idxm(MatStencil_i,1) = i
1379: $ idxm(MatStencil_j,1) = j
1380: $ idxm(MatStencil_k,1) = k
1381: $ idxm(MatStencil_c,1) = c
1382: etc
1384: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
1385: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
1386: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
1387: DM_BOUNDARY_PERIODIC boundary type.
1389: 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
1390: a single value per point) you can skip filling those indices.
1392: Inspired by the structured grid interface to the HYPRE package
1393: (http://www.llnl.gov/CASC/hypre)
1395: Efficiency Alert:
1396: The routine MatSetValuesBlockedStencil() may offer much better efficiency
1397: for users of block sparse formats (MATSEQBAIJ and MATMPIBAIJ).
1399: Level: beginner
1401: Concepts: matrices^putting entries in
1403: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1404: MatSetValues(), MatSetValuesBlockedStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil
1405: @*/
1406: PetscErrorCode MatSetValuesStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1407: {
1409: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1410: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1411: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1414: if (!m || !n) return(0); /* no values to insert */
1421: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1422: jdxm = buf; jdxn = buf+m;
1423: } else {
1424: PetscMalloc2(m,&bufm,n,&bufn);
1425: jdxm = bufm; jdxn = bufn;
1426: }
1427: for (i=0; i<m; i++) {
1428: for (j=0; j<3-sdim; j++) dxm++;
1429: tmp = *dxm++ - starts[0];
1430: for (j=0; j<dim-1; j++) {
1431: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1432: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1433: }
1434: if (mat->stencil.noc) dxm++;
1435: jdxm[i] = tmp;
1436: }
1437: for (i=0; i<n; i++) {
1438: for (j=0; j<3-sdim; j++) dxn++;
1439: tmp = *dxn++ - starts[0];
1440: for (j=0; j<dim-1; j++) {
1441: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1442: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1443: }
1444: if (mat->stencil.noc) dxn++;
1445: jdxn[i] = tmp;
1446: }
1447: MatSetValuesLocal(mat,m,jdxm,n,jdxn,v,addv);
1448: PetscFree2(bufm,bufn);
1449: return(0);
1450: }
1454: /*@
1455: MatSetValuesBlockedStencil - Inserts or adds a block of values into a matrix.
1456: Using structured grid indexing
1458: Not Collective
1460: Input Parameters:
1461: + mat - the matrix
1462: . m - number of rows being entered
1463: . idxm - grid coordinates for matrix rows being entered
1464: . n - number of columns being entered
1465: . idxn - grid coordinates for matrix columns being entered
1466: . v - a logically two-dimensional array of values
1467: - addv - either ADD_VALUES or INSERT_VALUES, where
1468: ADD_VALUES adds values to any existing entries, and
1469: INSERT_VALUES replaces existing entries with new values
1471: Notes:
1472: By default the values, v, are row-oriented and unsorted.
1473: See MatSetOption() for other options.
1475: Calls to MatSetValuesBlockedStencil() with the INSERT_VALUES and ADD_VALUES
1476: options cannot be mixed without intervening calls to the assembly
1477: routines.
1479: The grid coordinates are across the entire grid, not just the local portion
1481: MatSetValuesBlockedStencil() uses 0-based row and column numbers in Fortran
1482: as well as in C.
1484: For setting/accessing vector values via array coordinates you can use the DMDAVecGetArray() routine
1486: In order to use this routine you must either obtain the matrix with DMCreateMatrix()
1487: or call MatSetBlockSize(), MatSetLocalToGlobalMapping() and MatSetStencil() first.
1489: The columns and rows in the stencil passed in MUST be contained within the
1490: ghost region of the given process as set with DMDACreateXXX() or MatSetStencil(). For example,
1491: if you create a DMDA with an overlap of one grid level and on a particular process its first
1492: local nonghost x logical coordinate is 6 (so its first ghost x logical coordinate is 5) the
1493: first i index you can use in your column and row indices in MatSetStencil() is 5.
1495: In Fortran idxm and idxn should be declared as
1496: $ MatStencil idxm(4,m),idxn(4,n)
1497: and the values inserted using
1498: $ idxm(MatStencil_i,1) = i
1499: $ idxm(MatStencil_j,1) = j
1500: $ idxm(MatStencil_k,1) = k
1501: etc
1503: Negative indices may be passed in idxm and idxn, these rows and columns are
1504: simply ignored. This allows easily inserting element stiffness matrices
1505: with homogeneous Dirchlet boundary conditions that you don't want represented
1506: in the matrix.
1508: Inspired by the structured grid interface to the HYPRE package
1509: (http://www.llnl.gov/CASC/hypre)
1511: Level: beginner
1513: Concepts: matrices^putting entries in
1515: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1516: MatSetValues(), MatSetValuesStencil(), MatSetStencil(), DMCreateMatrix(), DMDAVecGetArray(), MatStencil,
1517: MatSetBlockSize(), MatSetLocalToGlobalMapping()
1518: @*/
1519: PetscErrorCode MatSetValuesBlockedStencil(Mat mat,PetscInt m,const MatStencil idxm[],PetscInt n,const MatStencil idxn[],const PetscScalar v[],InsertMode addv)
1520: {
1522: PetscInt buf[8192],*bufm=0,*bufn=0,*jdxm,*jdxn;
1523: PetscInt j,i,dim = mat->stencil.dim,*dims = mat->stencil.dims+1,tmp;
1524: PetscInt *starts = mat->stencil.starts,*dxm = (PetscInt*)idxm,*dxn = (PetscInt*)idxn,sdim = dim - (1 - (PetscInt)mat->stencil.noc);
1527: if (!m || !n) return(0); /* no values to insert */
1534: if ((m+n) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1535: jdxm = buf; jdxn = buf+m;
1536: } else {
1537: PetscMalloc2(m,&bufm,n,&bufn);
1538: jdxm = bufm; jdxn = bufn;
1539: }
1540: for (i=0; i<m; i++) {
1541: for (j=0; j<3-sdim; j++) dxm++;
1542: tmp = *dxm++ - starts[0];
1543: for (j=0; j<sdim-1; j++) {
1544: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1545: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
1546: }
1547: dxm++;
1548: jdxm[i] = tmp;
1549: }
1550: for (i=0; i<n; i++) {
1551: for (j=0; j<3-sdim; j++) dxn++;
1552: tmp = *dxn++ - starts[0];
1553: for (j=0; j<sdim-1; j++) {
1554: if ((*dxn++ - starts[j+1]) < 0 || tmp < 0) tmp = -1;
1555: else tmp = tmp*dims[j] + *(dxn-1) - starts[j+1];
1556: }
1557: dxn++;
1558: jdxn[i] = tmp;
1559: }
1560: MatSetValuesBlockedLocal(mat,m,jdxm,n,jdxn,v,addv);
1561: PetscFree2(bufm,bufn);
1562: #if defined(PETSC_HAVE_CUSP)
1563: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1564: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1565: }
1566: #elif defined(PETSC_HAVE_VIENNACL)
1567: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1568: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1569: }
1570: #elif defined(PETSC_HAVE_VECCUDA)
1571: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1572: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1573: }
1574: #endif
1575: return(0);
1576: }
1580: /*@
1581: MatSetStencil - Sets the grid information for setting values into a matrix via
1582: MatSetValuesStencil()
1584: Not Collective
1586: Input Parameters:
1587: + mat - the matrix
1588: . dim - dimension of the grid 1, 2, or 3
1589: . dims - number of grid points in x, y, and z direction, including ghost points on your processor
1590: . starts - starting point of ghost nodes on your processor in x, y, and z direction
1591: - dof - number of degrees of freedom per node
1594: Inspired by the structured grid interface to the HYPRE package
1595: (www.llnl.gov/CASC/hyper)
1597: For matrices generated with DMCreateMatrix() this routine is automatically called and so not needed by the
1598: user.
1600: Level: beginner
1602: Concepts: matrices^putting entries in
1604: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal()
1605: MatSetValues(), MatSetValuesBlockedStencil(), MatSetValuesStencil()
1606: @*/
1607: PetscErrorCode MatSetStencil(Mat mat,PetscInt dim,const PetscInt dims[],const PetscInt starts[],PetscInt dof)
1608: {
1609: PetscInt i;
1616: mat->stencil.dim = dim + (dof > 1);
1617: for (i=0; i<dim; i++) {
1618: mat->stencil.dims[i] = dims[dim-i-1]; /* copy the values in backwards */
1619: mat->stencil.starts[i] = starts[dim-i-1];
1620: }
1621: mat->stencil.dims[dim] = dof;
1622: mat->stencil.starts[dim] = 0;
1623: mat->stencil.noc = (PetscBool)(dof == 1);
1624: return(0);
1625: }
1629: /*@
1630: MatSetValuesBlocked - Inserts or adds a block of values into a matrix.
1632: Not Collective
1634: Input Parameters:
1635: + mat - the matrix
1636: . v - a logically two-dimensional array of values
1637: . m, idxm - the number of block rows and their global block indices
1638: . n, idxn - the number of block columns and their global block indices
1639: - addv - either ADD_VALUES or INSERT_VALUES, where
1640: ADD_VALUES adds values to any existing entries, and
1641: INSERT_VALUES replaces existing entries with new values
1643: Notes:
1644: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call
1645: MatXXXXSetPreallocation() or MatSetUp() before using this routine.
1647: The m and n count the NUMBER of blocks in the row direction and column direction,
1648: NOT the total number of rows/columns; for example, if the block size is 2 and
1649: you are passing in values for rows 2,3,4,5 then m would be 2 (not 4).
1650: The values in idxm would be 1 2; that is the first index for each block divided by
1651: the block size.
1653: Note that you must call MatSetBlockSize() when constructing this matrix (before
1654: preallocating it).
1656: By default the values, v, are row-oriented, so the layout of
1657: v is the same as for MatSetValues(). See MatSetOption() for other options.
1659: Calls to MatSetValuesBlocked() with the INSERT_VALUES and ADD_VALUES
1660: options cannot be mixed without intervening calls to the assembly
1661: routines.
1663: MatSetValuesBlocked() uses 0-based row and column numbers in Fortran
1664: as well as in C.
1666: Negative indices may be passed in idxm and idxn, these rows and columns are
1667: simply ignored. This allows easily inserting element stiffness matrices
1668: with homogeneous Dirchlet boundary conditions that you don't want represented
1669: in the matrix.
1671: Each time an entry is set within a sparse matrix via MatSetValues(),
1672: internal searching must be done to determine where to place the
1673: data in the matrix storage space. By instead inserting blocks of
1674: entries via MatSetValuesBlocked(), the overhead of matrix assembly is
1675: reduced.
1677: Example:
1678: $ Suppose m=n=2 and block size(bs) = 2 The array is
1679: $
1680: $ 1 2 | 3 4
1681: $ 5 6 | 7 8
1682: $ - - - | - - -
1683: $ 9 10 | 11 12
1684: $ 13 14 | 15 16
1685: $
1686: $ v[] should be passed in like
1687: $ v[] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
1688: $
1689: $ If you are not using row oriented storage of v (that is you called MatSetOption(mat,MAT_ROW_ORIENTED,PETSC_FALSE)) then
1690: $ v[] = [1,5,9,13,2,6,10,14,3,7,11,15,4,8,12,16]
1692: Level: intermediate
1694: Concepts: matrices^putting entries in blocked
1696: .seealso: MatSetBlockSize(), MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesBlockedLocal()
1697: @*/
1698: PetscErrorCode MatSetValuesBlocked(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],const PetscScalar v[],InsertMode addv)
1699: {
1705: if (!m || !n) return(0); /* no values to insert */
1709: MatCheckPreallocated(mat,1);
1710: if (mat->insertmode == NOT_SET_VALUES) {
1711: mat->insertmode = addv;
1712: }
1713: #if defined(PETSC_USE_DEBUG)
1714: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
1715: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1716: if (!mat->ops->setvaluesblocked && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1717: #endif
1719: if (mat->assembled) {
1720: mat->was_assembled = PETSC_TRUE;
1721: mat->assembled = PETSC_FALSE;
1722: }
1723: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
1724: if (mat->ops->setvaluesblocked) {
1725: (*mat->ops->setvaluesblocked)(mat,m,idxm,n,idxn,v,addv);
1726: } else {
1727: PetscInt buf[8192],*bufr=0,*bufc=0,*iidxm,*iidxn;
1728: PetscInt i,j,bs,cbs;
1729: MatGetBlockSizes(mat,&bs,&cbs);
1730: if (m*bs+n*cbs <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
1731: iidxm = buf; iidxn = buf + m*bs;
1732: } else {
1733: PetscMalloc2(m*bs,&bufr,n*cbs,&bufc);
1734: iidxm = bufr; iidxn = bufc;
1735: }
1736: for (i=0; i<m; i++) {
1737: for (j=0; j<bs; j++) {
1738: iidxm[i*bs+j] = bs*idxm[i] + j;
1739: }
1740: }
1741: for (i=0; i<n; i++) {
1742: for (j=0; j<cbs; j++) {
1743: iidxn[i*cbs+j] = cbs*idxn[i] + j;
1744: }
1745: }
1746: MatSetValues(mat,m*bs,iidxm,n*cbs,iidxn,v,addv);
1747: PetscFree2(bufr,bufc);
1748: }
1749: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
1750: #if defined(PETSC_HAVE_CUSP)
1751: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
1752: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
1753: }
1754: #elif defined(PETSC_HAVE_VIENNACL)
1755: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
1756: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
1757: }
1758: #elif defined(PETSC_HAVE_VECCUDA)
1759: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
1760: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
1761: }
1762: #endif
1763: return(0);
1764: }
1768: /*@
1769: MatGetValues - Gets a block of values from a matrix.
1771: Not Collective; currently only returns a local block
1773: Input Parameters:
1774: + mat - the matrix
1775: . v - a logically two-dimensional array for storing the values
1776: . m, idxm - the number of rows and their global indices
1777: - n, idxn - the number of columns and their global indices
1779: Notes:
1780: The user must allocate space (m*n PetscScalars) for the values, v.
1781: The values, v, are then returned in a row-oriented format,
1782: analogous to that used by default in MatSetValues().
1784: MatGetValues() uses 0-based row and column numbers in
1785: Fortran as well as in C.
1787: MatGetValues() requires that the matrix has been assembled
1788: with MatAssemblyBegin()/MatAssemblyEnd(). Thus, calls to
1789: MatSetValues() and MatGetValues() CANNOT be made in succession
1790: without intermediate matrix assembly.
1792: Negative row or column indices will be ignored and those locations in v[] will be
1793: left unchanged.
1795: Level: advanced
1797: Concepts: matrices^accessing values
1799: .seealso: MatGetRow(), MatGetSubMatrices(), MatSetValues()
1800: @*/
1801: PetscErrorCode MatGetValues(Mat mat,PetscInt m,const PetscInt idxm[],PetscInt n,const PetscInt idxn[],PetscScalar v[])
1802: {
1808: if (!m || !n) return(0);
1812: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
1813: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1814: if (!mat->ops->getvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
1815: MatCheckPreallocated(mat,1);
1817: PetscLogEventBegin(MAT_GetValues,mat,0,0,0);
1818: (*mat->ops->getvalues)(mat,m,idxm,n,idxn,v);
1819: PetscLogEventEnd(MAT_GetValues,mat,0,0,0);
1820: return(0);
1821: }
1825: /*@
1826: MatSetValuesBatch - Adds (ADD_VALUES) many blocks of values into a matrix at once. The blocks must all be square and
1827: the same size. Currently, this can only be called once and creates the given matrix.
1829: Not Collective
1831: Input Parameters:
1832: + mat - the matrix
1833: . nb - the number of blocks
1834: . bs - the number of rows (and columns) in each block
1835: . rows - a concatenation of the rows for each block
1836: - v - a concatenation of logically two-dimensional arrays of values
1838: Notes:
1839: In the future, we will extend this routine to handle rectangular blocks, and to allow multiple calls for a given matrix.
1841: Level: advanced
1843: Concepts: matrices^putting entries in
1845: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
1846: InsertMode, INSERT_VALUES, ADD_VALUES, MatSetValues()
1847: @*/
1848: PetscErrorCode MatSetValuesBatch(Mat mat, PetscInt nb, PetscInt bs, PetscInt rows[], const PetscScalar v[])
1849: {
1857: #if defined(PETSC_USE_DEBUG)
1858: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
1859: #endif
1861: PetscLogEventBegin(MAT_SetValuesBatch,mat,0,0,0);
1862: if (mat->ops->setvaluesbatch) {
1863: (*mat->ops->setvaluesbatch)(mat,nb,bs,rows,v);
1864: } else {
1865: PetscInt b;
1866: for (b = 0; b < nb; ++b) {
1867: MatSetValues(mat, bs, &rows[b*bs], bs, &rows[b*bs], &v[b*bs*bs], ADD_VALUES);
1868: }
1869: }
1870: PetscLogEventEnd(MAT_SetValuesBatch,mat,0,0,0);
1871: return(0);
1872: }
1876: /*@
1877: MatSetLocalToGlobalMapping - Sets a local-to-global numbering for use by
1878: the routine MatSetValuesLocal() to allow users to insert matrix entries
1879: using a local (per-processor) numbering.
1881: Not Collective
1883: Input Parameters:
1884: + x - the matrix
1885: . rmapping - row mapping created with ISLocalToGlobalMappingCreate() or ISLocalToGlobalMappingCreateIS()
1886: - cmapping - column mapping
1888: Level: intermediate
1890: Concepts: matrices^local to global mapping
1891: Concepts: local to global mapping^for matrices
1893: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetValuesLocal()
1894: @*/
1895: PetscErrorCode MatSetLocalToGlobalMapping(Mat x,ISLocalToGlobalMapping rmapping,ISLocalToGlobalMapping cmapping)
1896: {
1905: if (x->ops->setlocaltoglobalmapping) {
1906: (*x->ops->setlocaltoglobalmapping)(x,rmapping,cmapping);
1907: } else {
1908: PetscLayoutSetISLocalToGlobalMapping(x->rmap,rmapping);
1909: PetscLayoutSetISLocalToGlobalMapping(x->cmap,cmapping);
1910: }
1911: return(0);
1912: }
1917: /*@
1918: MatGetLocalToGlobalMapping - Gets the local-to-global numbering set by MatSetLocalToGlobalMapping()
1920: Not Collective
1922: Input Parameters:
1923: . A - the matrix
1925: Output Parameters:
1926: + rmapping - row mapping
1927: - cmapping - column mapping
1929: Level: advanced
1931: Concepts: matrices^local to global mapping
1932: Concepts: local to global mapping^for matrices
1934: .seealso: MatSetValuesLocal()
1935: @*/
1936: PetscErrorCode MatGetLocalToGlobalMapping(Mat A,ISLocalToGlobalMapping *rmapping,ISLocalToGlobalMapping *cmapping)
1937: {
1943: if (rmapping) *rmapping = A->rmap->mapping;
1944: if (cmapping) *cmapping = A->cmap->mapping;
1945: return(0);
1946: }
1950: /*@
1951: MatGetLayouts - Gets the PetscLayout objects for rows and columns
1953: Not Collective
1955: Input Parameters:
1956: . A - the matrix
1958: Output Parameters:
1959: + rmap - row layout
1960: - cmap - column layout
1962: Level: advanced
1964: .seealso: MatCreateVecs(), MatGetLocalToGlobalMapping()
1965: @*/
1966: PetscErrorCode MatGetLayouts(Mat A,PetscLayout *rmap,PetscLayout *cmap)
1967: {
1973: if (rmap) *rmap = A->rmap;
1974: if (cmap) *cmap = A->cmap;
1975: return(0);
1976: }
1980: /*@
1981: MatSetValuesLocal - Inserts or adds values into certain locations of a matrix,
1982: using a local ordering of the nodes.
1984: Not Collective
1986: Input Parameters:
1987: + x - the matrix
1988: . nrow, irow - number of rows and their local indices
1989: . ncol, icol - number of columns and their local indices
1990: . y - a logically two-dimensional array of values
1991: - addv - either INSERT_VALUES or ADD_VALUES, where
1992: ADD_VALUES adds values to any existing entries, and
1993: INSERT_VALUES replaces existing entries with new values
1995: Notes:
1996: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
1997: MatSetUp() before using this routine
1999: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetLocalToGlobalMapping() before using this routine
2001: Calls to MatSetValuesLocal() with the INSERT_VALUES and ADD_VALUES
2002: options cannot be mixed without intervening calls to the assembly
2003: routines.
2005: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2006: MUST be called after all calls to MatSetValuesLocal() have been completed.
2008: Level: intermediate
2010: Concepts: matrices^putting entries in with local numbering
2012: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), MatSetValues(), MatSetLocalToGlobalMapping(),
2013: MatSetValueLocal()
2014: @*/
2015: PetscErrorCode MatSetValuesLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2016: {
2022: MatCheckPreallocated(mat,1);
2023: if (!nrow || !ncol) return(0); /* no values to insert */
2027: if (mat->insertmode == NOT_SET_VALUES) {
2028: mat->insertmode = addv;
2029: }
2030: #if defined(PETSC_USE_DEBUG)
2031: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2032: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2033: if (!mat->ops->setvalueslocal && !mat->ops->setvalues) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2034: #endif
2036: if (mat->assembled) {
2037: mat->was_assembled = PETSC_TRUE;
2038: mat->assembled = PETSC_FALSE;
2039: }
2040: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2041: if (mat->ops->setvalueslocal) {
2042: (*mat->ops->setvalueslocal)(mat,nrow,irow,ncol,icol,y,addv);
2043: } else {
2044: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2045: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2046: irowm = buf; icolm = buf+nrow;
2047: } else {
2048: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2049: irowm = bufr; icolm = bufc;
2050: }
2051: ISLocalToGlobalMappingApply(mat->rmap->mapping,nrow,irow,irowm);
2052: ISLocalToGlobalMappingApply(mat->cmap->mapping,ncol,icol,icolm);
2053: MatSetValues(mat,nrow,irowm,ncol,icolm,y,addv);
2054: PetscFree2(bufr,bufc);
2055: }
2056: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2057: #if defined(PETSC_HAVE_CUSP)
2058: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2059: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2060: }
2061: #elif defined(PETSC_HAVE_VIENNACL)
2062: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2063: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2064: }
2065: #elif defined(PETSC_HAVE_VECCUDA)
2066: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2067: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2068: }
2069: #endif
2070: return(0);
2071: }
2075: /*@
2076: MatSetValuesBlockedLocal - Inserts or adds values into certain locations of a matrix,
2077: using a local ordering of the nodes a block at a time.
2079: Not Collective
2081: Input Parameters:
2082: + x - the matrix
2083: . nrow, irow - number of rows and their local indices
2084: . ncol, icol - number of columns and their local indices
2085: . y - a logically two-dimensional array of values
2086: - addv - either INSERT_VALUES or ADD_VALUES, where
2087: ADD_VALUES adds values to any existing entries, and
2088: INSERT_VALUES replaces existing entries with new values
2090: Notes:
2091: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatXXXXSetPreallocation() or
2092: MatSetUp() before using this routine
2094: If you create the matrix yourself (that is not with a call to DMCreateMatrix()) then you MUST call MatSetBlockSize() and MatSetLocalToGlobalMapping()
2095: before using this routineBefore calling MatSetValuesLocal(), the user must first set the
2097: Calls to MatSetValuesBlockedLocal() with the INSERT_VALUES and ADD_VALUES
2098: options cannot be mixed without intervening calls to the assembly
2099: routines.
2101: These values may be cached, so MatAssemblyBegin() and MatAssemblyEnd()
2102: MUST be called after all calls to MatSetValuesBlockedLocal() have been completed.
2104: Level: intermediate
2106: Concepts: matrices^putting blocked values in with local numbering
2108: .seealso: MatSetBlockSize(), MatSetLocalToGlobalMapping(), MatAssemblyBegin(), MatAssemblyEnd(),
2109: MatSetValuesLocal(), MatSetValuesBlocked()
2110: @*/
2111: PetscErrorCode MatSetValuesBlockedLocal(Mat mat,PetscInt nrow,const PetscInt irow[],PetscInt ncol,const PetscInt icol[],const PetscScalar y[],InsertMode addv)
2112: {
2118: MatCheckPreallocated(mat,1);
2119: if (!nrow || !ncol) return(0); /* no values to insert */
2123: if (mat->insertmode == NOT_SET_VALUES) {
2124: mat->insertmode = addv;
2125: }
2126: #if defined(PETSC_USE_DEBUG)
2127: else if (mat->insertmode != addv) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Cannot mix add values and insert values");
2128: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2129: 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);
2130: #endif
2132: if (mat->assembled) {
2133: mat->was_assembled = PETSC_TRUE;
2134: mat->assembled = PETSC_FALSE;
2135: }
2136: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
2137: if (mat->ops->setvaluesblockedlocal) {
2138: (*mat->ops->setvaluesblockedlocal)(mat,nrow,irow,ncol,icol,y,addv);
2139: } else {
2140: PetscInt buf[8192],*bufr=0,*bufc=0,*irowm,*icolm;
2141: if ((nrow+ncol) <= (PetscInt)(sizeof(buf)/sizeof(PetscInt))) {
2142: irowm = buf; icolm = buf + nrow;
2143: } else {
2144: PetscMalloc2(nrow,&bufr,ncol,&bufc);
2145: irowm = bufr; icolm = bufc;
2146: }
2147: ISLocalToGlobalMappingApplyBlock(mat->rmap->mapping,nrow,irow,irowm);
2148: ISLocalToGlobalMappingApplyBlock(mat->cmap->mapping,ncol,icol,icolm);
2149: MatSetValuesBlocked(mat,nrow,irowm,ncol,icolm,y,addv);
2150: PetscFree2(bufr,bufc);
2151: }
2152: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
2153: #if defined(PETSC_HAVE_CUSP)
2154: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
2155: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
2156: }
2157: #elif defined(PETSC_HAVE_VIENNACL)
2158: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
2159: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
2160: }
2161: #elif defined(PETSC_HAVE_VECCUDA)
2162: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
2163: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
2164: }
2165: #endif
2166: return(0);
2167: }
2171: /*@
2172: MatMultDiagonalBlock - Computes the matrix-vector product, y = Dx. Where D is defined by the inode or block structure of the diagonal
2174: Collective on Mat and Vec
2176: Input Parameters:
2177: + mat - the matrix
2178: - x - the vector to be multiplied
2180: Output Parameters:
2181: . y - the result
2183: Notes:
2184: The vectors x and y cannot be the same. I.e., one cannot
2185: call MatMult(A,y,y).
2187: Level: developer
2189: Concepts: matrix-vector product
2191: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2192: @*/
2193: PetscErrorCode MatMultDiagonalBlock(Mat mat,Vec x,Vec y)
2194: {
2203: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2204: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2205: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2206: MatCheckPreallocated(mat,1);
2208: if (!mat->ops->multdiagonalblock) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2209: (*mat->ops->multdiagonalblock)(mat,x,y);
2210: PetscObjectStateIncrease((PetscObject)y);
2211: return(0);
2212: }
2214: /* --------------------------------------------------------*/
2217: /*@
2218: MatMult - Computes the matrix-vector product, y = Ax.
2220: Neighbor-wise Collective on Mat and Vec
2222: Input Parameters:
2223: + mat - the matrix
2224: - x - the vector to be multiplied
2226: Output Parameters:
2227: . y - the result
2229: Notes:
2230: The vectors x and y cannot be the same. I.e., one cannot
2231: call MatMult(A,y,y).
2233: Level: beginner
2235: Concepts: matrix-vector product
2237: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2238: @*/
2239: PetscErrorCode MatMult(Mat mat,Vec x,Vec y)
2240: {
2248: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2249: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2250: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2251: #if !defined(PETSC_HAVE_CONSTRAINTS)
2252: 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);
2253: 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);
2254: 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);
2255: #endif
2256: VecLocked(y,3);
2257: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2258: MatCheckPreallocated(mat,1);
2260: VecLockPush(x);
2261: if (!mat->ops->mult) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply defined");
2262: PetscLogEventBegin(MAT_Mult,mat,x,y,0);
2263: (*mat->ops->mult)(mat,x,y);
2264: PetscLogEventEnd(MAT_Mult,mat,x,y,0);
2265: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2266: VecLockPop(x);
2267: return(0);
2268: }
2272: /*@
2273: MatMultTranspose - Computes matrix transpose times a vector.
2275: Neighbor-wise Collective on Mat and Vec
2277: Input Parameters:
2278: + mat - the matrix
2279: - x - the vector to be multilplied
2281: Output Parameters:
2282: . y - the result
2284: Notes:
2285: The vectors x and y cannot be the same. I.e., one cannot
2286: call MatMultTranspose(A,y,y).
2288: For complex numbers this does NOT compute the Hermitian (complex conjugate) transpose multiple,
2289: use MatMultHermitianTranspose()
2291: Level: beginner
2293: Concepts: matrix vector product^transpose
2295: .seealso: MatMult(), MatMultAdd(), MatMultTransposeAdd(), MatMultHermitianTranspose(), MatTranspose()
2296: @*/
2297: PetscErrorCode MatMultTranspose(Mat mat,Vec x,Vec y)
2298: {
2307: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2308: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2309: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2310: #if !defined(PETSC_HAVE_CONSTRAINTS)
2311: 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);
2312: 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);
2313: #endif
2314: if (mat->erroriffailure) {VecValidValues(x,2,PETSC_TRUE);}
2315: MatCheckPreallocated(mat,1);
2317: if (!mat->ops->multtranspose) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a multiply tranpose defined");
2318: PetscLogEventBegin(MAT_MultTranspose,mat,x,y,0);
2319: VecLockPush(x);
2320: (*mat->ops->multtranspose)(mat,x,y);
2321: VecLockPop(x);
2322: PetscLogEventEnd(MAT_MultTranspose,mat,x,y,0);
2323: PetscObjectStateIncrease((PetscObject)y);
2324: if (mat->erroriffailure) {VecValidValues(y,3,PETSC_FALSE);}
2325: return(0);
2326: }
2330: /*@
2331: MatMultHermitianTranspose - Computes matrix Hermitian transpose times a vector.
2333: Neighbor-wise Collective on Mat and Vec
2335: Input Parameters:
2336: + mat - the matrix
2337: - x - the vector to be multilplied
2339: Output Parameters:
2340: . y - the result
2342: Notes:
2343: The vectors x and y cannot be the same. I.e., one cannot
2344: call MatMultHermitianTranspose(A,y,y).
2346: Also called the conjugate transpose, complex conjugate transpose, or adjoint.
2348: For real numbers MatMultTranspose() and MatMultHermitianTranspose() are identical.
2350: Level: beginner
2352: Concepts: matrix vector product^transpose
2354: .seealso: MatMult(), MatMultAdd(), MatMultHermitianTransposeAdd(), MatMultTranspose()
2355: @*/
2356: PetscErrorCode MatMultHermitianTranspose(Mat mat,Vec x,Vec y)
2357: {
2359: Vec w;
2367: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2368: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2369: if (x == y) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2370: #if !defined(PETSC_HAVE_CONSTRAINTS)
2371: 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);
2372: 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);
2373: #endif
2374: MatCheckPreallocated(mat,1);
2376: PetscLogEventBegin(MAT_MultHermitianTranspose,mat,x,y,0);
2377: if (mat->ops->multhermitiantranspose) {
2378: VecLockPush(x);
2379: (*mat->ops->multhermitiantranspose)(mat,x,y);
2380: VecLockPop(x);
2381: } else {
2382: VecDuplicate(x,&w);
2383: VecCopy(x,w);
2384: VecConjugate(w);
2385: MatMultTranspose(mat,w,y);
2386: VecDestroy(&w);
2387: VecConjugate(y);
2388: }
2389: PetscLogEventEnd(MAT_MultHermitianTranspose,mat,x,y,0);
2390: PetscObjectStateIncrease((PetscObject)y);
2391: return(0);
2392: }
2396: /*@
2397: MatMultAdd - Computes v3 = v2 + A * v1.
2399: Neighbor-wise Collective on Mat and Vec
2401: Input Parameters:
2402: + mat - the matrix
2403: - v1, v2 - the vectors
2405: Output Parameters:
2406: . v3 - the result
2408: Notes:
2409: The vectors v1 and v3 cannot be the same. I.e., one cannot
2410: call MatMultAdd(A,v1,v2,v1).
2412: Level: beginner
2414: Concepts: matrix vector product^addition
2416: .seealso: MatMultTranspose(), MatMult(), MatMultTransposeAdd()
2417: @*/
2418: PetscErrorCode MatMultAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2419: {
2429: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2430: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2431: 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);
2432: /* 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);
2433: 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); */
2434: 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);
2435: 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);
2436: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2437: MatCheckPreallocated(mat,1);
2439: if (!mat->ops->multadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"No MatMultAdd() for matrix type '%s'",((PetscObject)mat)->type_name);
2440: PetscLogEventBegin(MAT_MultAdd,mat,v1,v2,v3);
2441: VecLockPush(v1);
2442: (*mat->ops->multadd)(mat,v1,v2,v3);
2443: VecLockPop(v1);
2444: PetscLogEventEnd(MAT_MultAdd,mat,v1,v2,v3);
2445: PetscObjectStateIncrease((PetscObject)v3);
2446: return(0);
2447: }
2451: /*@
2452: MatMultTransposeAdd - Computes v3 = v2 + A' * v1.
2454: Neighbor-wise Collective on Mat and Vec
2456: Input Parameters:
2457: + mat - the matrix
2458: - v1, v2 - the vectors
2460: Output Parameters:
2461: . v3 - the result
2463: Notes:
2464: The vectors v1 and v3 cannot be the same. I.e., one cannot
2465: call MatMultTransposeAdd(A,v1,v2,v1).
2467: Level: beginner
2469: Concepts: matrix vector product^transpose and addition
2471: .seealso: MatMultTranspose(), MatMultAdd(), MatMult()
2472: @*/
2473: PetscErrorCode MatMultTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2474: {
2484: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2485: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2486: if (!mat->ops->multtransposeadd) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2487: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2488: 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);
2489: 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);
2490: 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);
2491: MatCheckPreallocated(mat,1);
2493: PetscLogEventBegin(MAT_MultTransposeAdd,mat,v1,v2,v3);
2494: VecLockPush(v1);
2495: (*mat->ops->multtransposeadd)(mat,v1,v2,v3);
2496: VecLockPop(v1);
2497: PetscLogEventEnd(MAT_MultTransposeAdd,mat,v1,v2,v3);
2498: PetscObjectStateIncrease((PetscObject)v3);
2499: return(0);
2500: }
2504: /*@
2505: MatMultHermitianTransposeAdd - Computes v3 = v2 + A^H * v1.
2507: Neighbor-wise Collective on Mat and Vec
2509: Input Parameters:
2510: + mat - the matrix
2511: - v1, v2 - the vectors
2513: Output Parameters:
2514: . v3 - the result
2516: Notes:
2517: The vectors v1 and v3 cannot be the same. I.e., one cannot
2518: call MatMultHermitianTransposeAdd(A,v1,v2,v1).
2520: Level: beginner
2522: Concepts: matrix vector product^transpose and addition
2524: .seealso: MatMultHermitianTranspose(), MatMultTranspose(), MatMultAdd(), MatMult()
2525: @*/
2526: PetscErrorCode MatMultHermitianTransposeAdd(Mat mat,Vec v1,Vec v2,Vec v3)
2527: {
2537: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2538: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2539: if (v1 == v3) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"v1 and v3 must be different vectors");
2540: 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);
2541: 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);
2542: 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);
2543: MatCheckPreallocated(mat,1);
2545: PetscLogEventBegin(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2546: VecLockPush(v1);
2547: if (mat->ops->multhermitiantransposeadd) {
2548: (*mat->ops->multhermitiantransposeadd)(mat,v1,v2,v3);
2549: } else {
2550: Vec w,z;
2551: VecDuplicate(v1,&w);
2552: VecCopy(v1,w);
2553: VecConjugate(w);
2554: VecDuplicate(v3,&z);
2555: MatMultTranspose(mat,w,z);
2556: VecDestroy(&w);
2557: VecConjugate(z);
2558: VecWAXPY(v3,1.0,v2,z);
2559: VecDestroy(&z);
2560: }
2561: VecLockPop(v1);
2562: PetscLogEventEnd(MAT_MultHermitianTransposeAdd,mat,v1,v2,v3);
2563: PetscObjectStateIncrease((PetscObject)v3);
2564: return(0);
2565: }
2569: /*@
2570: MatMultConstrained - The inner multiplication routine for a
2571: constrained matrix P^T A P.
2573: Neighbor-wise Collective on Mat and Vec
2575: Input Parameters:
2576: + mat - the matrix
2577: - x - the vector to be multilplied
2579: Output Parameters:
2580: . y - the result
2582: Notes:
2583: The vectors x and y cannot be the same. I.e., one cannot
2584: call MatMult(A,y,y).
2586: Level: beginner
2588: .keywords: matrix, multiply, matrix-vector product, constraint
2589: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2590: @*/
2591: PetscErrorCode MatMultConstrained(Mat mat,Vec x,Vec y)
2592: {
2599: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2600: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2601: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2602: 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);
2603: 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);
2604: 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);
2606: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2607: VecLockPush(x);
2608: (*mat->ops->multconstrained)(mat,x,y);
2609: VecLockPop(x);
2610: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2611: PetscObjectStateIncrease((PetscObject)y);
2612: return(0);
2613: }
2617: /*@
2618: MatMultTransposeConstrained - The inner multiplication routine for a
2619: constrained matrix P^T A^T P.
2621: Neighbor-wise Collective on Mat and Vec
2623: Input Parameters:
2624: + mat - the matrix
2625: - x - the vector to be multilplied
2627: Output Parameters:
2628: . y - the result
2630: Notes:
2631: The vectors x and y cannot be the same. I.e., one cannot
2632: call MatMult(A,y,y).
2634: Level: beginner
2636: .keywords: matrix, multiply, matrix-vector product, constraint
2637: .seealso: MatMult(), MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
2638: @*/
2639: PetscErrorCode MatMultTransposeConstrained(Mat mat,Vec x,Vec y)
2640: {
2647: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2648: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2649: if (x == y) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"x and y must be different vectors");
2650: 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);
2651: 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);
2653: PetscLogEventBegin(MAT_MultConstrained,mat,x,y,0);
2654: (*mat->ops->multtransposeconstrained)(mat,x,y);
2655: PetscLogEventEnd(MAT_MultConstrained,mat,x,y,0);
2656: PetscObjectStateIncrease((PetscObject)y);
2657: return(0);
2658: }
2662: /*@C
2663: MatGetFactorType - gets the type of factorization it is
2665: Note Collective
2666: as the flag
2668: Input Parameters:
2669: . mat - the matrix
2671: Output Parameters:
2672: . t - the type, one of MAT_FACTOR_NONE, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ILU, MAT_FACTOR_ICC,MAT_FACTOR_ILUDT
2674: Level: intermediate
2676: .seealso: MatFactorType, MatGetFactor()
2677: @*/
2678: PetscErrorCode MatGetFactorType(Mat mat,MatFactorType *t)
2679: {
2683: *t = mat->factortype;
2684: return(0);
2685: }
2687: /* ------------------------------------------------------------*/
2690: /*@C
2691: MatGetInfo - Returns information about matrix storage (number of
2692: nonzeros, memory, etc.).
2694: Collective on Mat if MAT_GLOBAL_MAX or MAT_GLOBAL_SUM is used as the flag
2696: Input Parameters:
2697: . mat - the matrix
2699: Output Parameters:
2700: + flag - flag indicating the type of parameters to be returned
2701: (MAT_LOCAL - local matrix, MAT_GLOBAL_MAX - maximum over all processors,
2702: MAT_GLOBAL_SUM - sum over all processors)
2703: - info - matrix information context
2705: Notes:
2706: The MatInfo context contains a variety of matrix data, including
2707: number of nonzeros allocated and used, number of mallocs during
2708: matrix assembly, etc. Additional information for factored matrices
2709: is provided (such as the fill ratio, number of mallocs during
2710: factorization, etc.). Much of this info is printed to PETSC_STDOUT
2711: when using the runtime options
2712: $ -info -mat_view ::ascii_info
2714: Example for C/C++ Users:
2715: See the file ${PETSC_DIR}/include/petscmat.h for a complete list of
2716: data within the MatInfo context. For example,
2717: .vb
2718: MatInfo info;
2719: Mat A;
2720: double mal, nz_a, nz_u;
2722: MatGetInfo(A,MAT_LOCAL,&info);
2723: mal = info.mallocs;
2724: nz_a = info.nz_allocated;
2725: .ve
2727: Example for Fortran Users:
2728: Fortran users should declare info as a double precision
2729: array of dimension MAT_INFO_SIZE, and then extract the parameters
2730: of interest. See the file ${PETSC_DIR}/include/petsc/finclude/petscmat.h
2731: a complete list of parameter names.
2732: .vb
2733: double precision info(MAT_INFO_SIZE)
2734: double precision mal, nz_a
2735: Mat A
2736: integer ierr
2738: call MatGetInfo(A,MAT_LOCAL,info,ierr)
2739: mal = info(MAT_INFO_MALLOCS)
2740: nz_a = info(MAT_INFO_NZ_ALLOCATED)
2741: .ve
2743: Level: intermediate
2745: Concepts: matrices^getting information on
2747: Developer Note: fortran interface is not autogenerated as the f90
2748: interface defintion cannot be generated correctly [due to MatInfo]
2750: .seealso: MatStashGetInfo()
2752: @*/
2753: PetscErrorCode MatGetInfo(Mat mat,MatInfoType flag,MatInfo *info)
2754: {
2761: if (!mat->ops->getinfo) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2762: MatCheckPreallocated(mat,1);
2763: (*mat->ops->getinfo)(mat,flag,info);
2764: return(0);
2765: }
2767: /* ----------------------------------------------------------*/
2771: /*@C
2772: MatLUFactor - Performs in-place LU factorization of matrix.
2774: Collective on Mat
2776: Input Parameters:
2777: + mat - the matrix
2778: . row - row permutation
2779: . col - column permutation
2780: - info - options for factorization, includes
2781: $ fill - expected fill as ratio of original fill.
2782: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2783: $ Run with the option -info to determine an optimal value to use
2785: Notes:
2786: Most users should employ the simplified KSP interface for linear solvers
2787: instead of working directly with matrix algebra routines such as this.
2788: See, e.g., KSPCreate().
2790: This changes the state of the matrix to a factored matrix; it cannot be used
2791: for example with MatSetValues() unless one first calls MatSetUnfactored().
2793: Level: developer
2795: Concepts: matrices^LU factorization
2797: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(),
2798: MatGetOrdering(), MatSetUnfactored(), MatFactorInfo, MatGetFactor()
2800: Developer Note: fortran interface is not autogenerated as the f90
2801: interface defintion cannot be generated correctly [due to MatFactorInfo]
2803: @*/
2804: PetscErrorCode MatLUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2805: {
2807: MatFactorInfo tinfo;
2815: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2816: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2817: if (!mat->ops->lufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2818: MatCheckPreallocated(mat,1);
2819: if (!info) {
2820: MatFactorInfoInitialize(&tinfo);
2821: info = &tinfo;
2822: }
2824: PetscLogEventBegin(MAT_LUFactor,mat,row,col,0);
2825: (*mat->ops->lufactor)(mat,row,col,info);
2826: PetscLogEventEnd(MAT_LUFactor,mat,row,col,0);
2827: PetscObjectStateIncrease((PetscObject)mat);
2828: return(0);
2829: }
2833: /*@C
2834: MatILUFactor - Performs in-place ILU factorization of matrix.
2836: Collective on Mat
2838: Input Parameters:
2839: + mat - the matrix
2840: . row - row permutation
2841: . col - column permutation
2842: - info - structure containing
2843: $ levels - number of levels of fill.
2844: $ expected fill - as ratio of original fill.
2845: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
2846: missing diagonal entries)
2848: Notes:
2849: Probably really in-place only when level of fill is zero, otherwise allocates
2850: new space to store factored matrix and deletes previous memory.
2852: Most users should employ the simplified KSP interface for linear solvers
2853: instead of working directly with matrix algebra routines such as this.
2854: See, e.g., KSPCreate().
2856: Level: developer
2858: Concepts: matrices^ILU factorization
2860: .seealso: MatILUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
2862: Developer Note: fortran interface is not autogenerated as the f90
2863: interface defintion cannot be generated correctly [due to MatFactorInfo]
2865: @*/
2866: PetscErrorCode MatILUFactor(Mat mat,IS row,IS col,const MatFactorInfo *info)
2867: {
2876: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
2877: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2878: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2879: if (!mat->ops->ilufactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
2880: MatCheckPreallocated(mat,1);
2882: PetscLogEventBegin(MAT_ILUFactor,mat,row,col,0);
2883: (*mat->ops->ilufactor)(mat,row,col,info);
2884: PetscLogEventEnd(MAT_ILUFactor,mat,row,col,0);
2885: PetscObjectStateIncrease((PetscObject)mat);
2886: return(0);
2887: }
2891: /*@C
2892: MatLUFactorSymbolic - Performs symbolic LU factorization of matrix.
2893: Call this routine before calling MatLUFactorNumeric().
2895: Collective on Mat
2897: Input Parameters:
2898: + fact - the factor matrix obtained with MatGetFactor()
2899: . mat - the matrix
2900: . row, col - row and column permutations
2901: - info - options for factorization, includes
2902: $ fill - expected fill as ratio of original fill.
2903: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
2904: $ Run with the option -info to determine an optimal value to use
2907: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
2909: Most users should employ the simplified KSP interface for linear solvers
2910: instead of working directly with matrix algebra routines such as this.
2911: See, e.g., KSPCreate().
2913: Level: developer
2915: Concepts: matrices^LU symbolic factorization
2917: .seealso: MatLUFactor(), MatLUFactorNumeric(), MatCholeskyFactor(), MatFactorInfo, MatFactorInfoInitialize()
2919: Developer Note: fortran interface is not autogenerated as the f90
2920: interface defintion cannot be generated correctly [due to MatFactorInfo]
2922: @*/
2923: PetscErrorCode MatLUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
2924: {
2934: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2935: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
2936: if (!(fact)->ops->lufactorsymbolic) {
2937: const MatSolverPackage spackage;
2938: MatFactorGetSolverPackage(fact,&spackage);
2939: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic LU using solver package %s",((PetscObject)mat)->type_name,spackage);
2940: }
2941: MatCheckPreallocated(mat,2);
2943: PetscLogEventBegin(MAT_LUFactorSymbolic,mat,row,col,0);
2944: (fact->ops->lufactorsymbolic)(fact,mat,row,col,info);
2945: PetscLogEventEnd(MAT_LUFactorSymbolic,mat,row,col,0);
2946: PetscObjectStateIncrease((PetscObject)fact);
2947: return(0);
2948: }
2952: /*@C
2953: MatLUFactorNumeric - Performs numeric LU factorization of a matrix.
2954: Call this routine after first calling MatLUFactorSymbolic().
2956: Collective on Mat
2958: Input Parameters:
2959: + fact - the factor matrix obtained with MatGetFactor()
2960: . mat - the matrix
2961: - info - options for factorization
2963: Notes:
2964: See MatLUFactor() for in-place factorization. See
2965: MatCholeskyFactorNumeric() for the symmetric, positive definite case.
2967: Most users should employ the simplified KSP interface for linear solvers
2968: instead of working directly with matrix algebra routines such as this.
2969: See, e.g., KSPCreate().
2971: Level: developer
2973: Concepts: matrices^LU numeric factorization
2975: .seealso: MatLUFactorSymbolic(), MatLUFactor(), MatCholeskyFactor()
2977: Developer Note: fortran interface is not autogenerated as the f90
2978: interface defintion cannot be generated correctly [due to MatFactorInfo]
2980: @*/
2981: PetscErrorCode MatLUFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
2982: {
2990: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
2991: 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);
2993: if (!(fact)->ops->lufactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric LU",((PetscObject)mat)->type_name);
2994: MatCheckPreallocated(mat,2);
2995: PetscLogEventBegin(MAT_LUFactorNumeric,mat,fact,0,0);
2996: (fact->ops->lufactornumeric)(fact,mat,info);
2997: PetscLogEventEnd(MAT_LUFactorNumeric,mat,fact,0,0);
2998: MatViewFromOptions(fact,NULL,"-mat_factor_view");
2999: PetscObjectStateIncrease((PetscObject)fact);
3000: return(0);
3001: }
3005: /*@C
3006: MatCholeskyFactor - Performs in-place Cholesky factorization of a
3007: symmetric matrix.
3009: Collective on Mat
3011: Input Parameters:
3012: + mat - the matrix
3013: . perm - row and column permutations
3014: - f - expected fill as ratio of original fill
3016: Notes:
3017: See MatLUFactor() for the nonsymmetric case. See also
3018: MatCholeskyFactorSymbolic(), and MatCholeskyFactorNumeric().
3020: Most users should employ the simplified KSP interface for linear solvers
3021: instead of working directly with matrix algebra routines such as this.
3022: See, e.g., KSPCreate().
3024: Level: developer
3026: Concepts: matrices^Cholesky factorization
3028: .seealso: MatLUFactor(), MatCholeskyFactorSymbolic(), MatCholeskyFactorNumeric()
3029: MatGetOrdering()
3031: Developer Note: fortran interface is not autogenerated as the f90
3032: interface defintion cannot be generated correctly [due to MatFactorInfo]
3034: @*/
3035: PetscErrorCode MatCholeskyFactor(Mat mat,IS perm,const MatFactorInfo *info)
3036: {
3044: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3045: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3046: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3047: if (!mat->ops->choleskyfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3048: MatCheckPreallocated(mat,1);
3050: PetscLogEventBegin(MAT_CholeskyFactor,mat,perm,0,0);
3051: (*mat->ops->choleskyfactor)(mat,perm,info);
3052: PetscLogEventEnd(MAT_CholeskyFactor,mat,perm,0,0);
3053: PetscObjectStateIncrease((PetscObject)mat);
3054: return(0);
3055: }
3059: /*@C
3060: MatCholeskyFactorSymbolic - Performs symbolic Cholesky factorization
3061: of a symmetric matrix.
3063: Collective on Mat
3065: Input Parameters:
3066: + fact - the factor matrix obtained with MatGetFactor()
3067: . mat - the matrix
3068: . perm - row and column permutations
3069: - info - options for factorization, includes
3070: $ fill - expected fill as ratio of original fill.
3071: $ dtcol - pivot tolerance (0 no pivot, 1 full column pivoting)
3072: $ Run with the option -info to determine an optimal value to use
3074: Notes:
3075: See MatLUFactorSymbolic() for the nonsymmetric case. See also
3076: MatCholeskyFactor() and MatCholeskyFactorNumeric().
3078: Most users should employ the simplified KSP interface for linear solvers
3079: instead of working directly with matrix algebra routines such as this.
3080: See, e.g., KSPCreate().
3082: Level: developer
3084: Concepts: matrices^Cholesky symbolic factorization
3086: .seealso: MatLUFactorSymbolic(), MatCholeskyFactor(), MatCholeskyFactorNumeric()
3087: MatGetOrdering()
3089: Developer Note: fortran interface is not autogenerated as the f90
3090: interface defintion cannot be generated correctly [due to MatFactorInfo]
3092: @*/
3093: PetscErrorCode MatCholeskyFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
3094: {
3103: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Matrix must be square");
3104: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3105: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3106: if (!(fact)->ops->choleskyfactorsymbolic) {
3107: const MatSolverPackage spackage;
3108: MatFactorGetSolverPackage(fact,&spackage);
3109: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s symbolic factor Cholesky using solver package %s",((PetscObject)mat)->type_name,spackage);
3110: }
3111: MatCheckPreallocated(mat,2);
3113: PetscLogEventBegin(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3114: (fact->ops->choleskyfactorsymbolic)(fact,mat,perm,info);
3115: PetscLogEventEnd(MAT_CholeskyFactorSymbolic,mat,perm,0,0);
3116: PetscObjectStateIncrease((PetscObject)fact);
3117: return(0);
3118: }
3122: /*@C
3123: MatCholeskyFactorNumeric - Performs numeric Cholesky factorization
3124: of a symmetric matrix. Call this routine after first calling
3125: MatCholeskyFactorSymbolic().
3127: Collective on Mat
3129: Input Parameters:
3130: + fact - the factor matrix obtained with MatGetFactor()
3131: . mat - the initial matrix
3132: . info - options for factorization
3133: - fact - the symbolic factor of mat
3136: Notes:
3137: Most users should employ the simplified KSP interface for linear solvers
3138: instead of working directly with matrix algebra routines such as this.
3139: See, e.g., KSPCreate().
3141: Level: developer
3143: Concepts: matrices^Cholesky numeric factorization
3145: .seealso: MatCholeskyFactorSymbolic(), MatCholeskyFactor(), MatLUFactorNumeric()
3147: Developer Note: fortran interface is not autogenerated as the f90
3148: interface defintion cannot be generated correctly [due to MatFactorInfo]
3150: @*/
3151: PetscErrorCode MatCholeskyFactorNumeric(Mat fact,Mat mat,const MatFactorInfo *info)
3152: {
3160: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3161: if (!(fact)->ops->choleskyfactornumeric) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s numeric factor Cholesky",((PetscObject)mat)->type_name);
3162: 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);
3163: MatCheckPreallocated(mat,2);
3165: PetscLogEventBegin(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3166: (fact->ops->choleskyfactornumeric)(fact,mat,info);
3167: PetscLogEventEnd(MAT_CholeskyFactorNumeric,mat,fact,0,0);
3168: MatViewFromOptions(fact,NULL,"-mat_factor_view");
3169: PetscObjectStateIncrease((PetscObject)fact);
3170: return(0);
3171: }
3173: /* ----------------------------------------------------------------*/
3176: /*@
3177: MatSolve - Solves A x = b, given a factored matrix.
3179: Neighbor-wise Collective on Mat and Vec
3181: Input Parameters:
3182: + mat - the factored matrix
3183: - b - the right-hand-side vector
3185: Output Parameter:
3186: . x - the result vector
3188: Notes:
3189: The vectors b and x cannot be the same. I.e., one cannot
3190: call MatSolve(A,x,x).
3192: Notes:
3193: Most users should employ the simplified KSP interface for linear solvers
3194: instead of working directly with matrix algebra routines such as this.
3195: See, e.g., KSPCreate().
3197: Level: developer
3199: Concepts: matrices^triangular solves
3201: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd()
3202: @*/
3203: PetscErrorCode MatSolve(Mat mat,Vec b,Vec x)
3204: {
3214: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3215: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3216: 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);
3217: 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);
3218: 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);
3219: if (!mat->rmap->N && !mat->cmap->N) return(0);
3220: if (!mat->ops->solve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3221: MatCheckPreallocated(mat,1);
3223: PetscLogEventBegin(MAT_Solve,mat,b,x,0);
3224: if (mat->errortype) {
3225: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3226: VecSetInf(x);
3227: } else {
3228: (*mat->ops->solve)(mat,b,x);
3229: }
3230: PetscLogEventEnd(MAT_Solve,mat,b,x,0);
3231: PetscObjectStateIncrease((PetscObject)x);
3232: return(0);
3233: }
3237: PetscErrorCode MatMatSolve_Basic(Mat A,Mat B,Mat X)
3238: {
3240: Vec b,x;
3241: PetscInt m,N,i;
3242: PetscScalar *bb,*xx;
3243: PetscBool flg;
3246: PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3247: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix");
3248: PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);
3249: if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix");
3251: MatDenseGetArray(B,&bb);
3252: MatDenseGetArray(X,&xx);
3253: MatGetLocalSize(B,&m,NULL); /* number local rows */
3254: MatGetSize(B,NULL,&N); /* total columns in dense matrix */
3255: MatCreateVecs(A,&x,&b);
3256: for (i=0; i<N; i++) {
3257: VecPlaceArray(b,bb + i*m);
3258: VecPlaceArray(x,xx + i*m);
3259: MatSolve(A,b,x);
3260: VecResetArray(x);
3261: VecResetArray(b);
3262: }
3263: VecDestroy(&b);
3264: VecDestroy(&x);
3265: MatDenseRestoreArray(B,&bb);
3266: MatDenseRestoreArray(X,&xx);
3267: return(0);
3268: }
3272: /*@
3273: MatMatSolve - Solves A X = B, given a factored matrix.
3275: Neighbor-wise Collective on Mat
3277: Input Parameters:
3278: + A - the factored matrix
3279: - B - the right-hand-side matrix (dense matrix)
3281: Output Parameter:
3282: . X - the result matrix (dense matrix)
3284: Notes:
3285: The matrices b and x cannot be the same. I.e., one cannot
3286: call MatMatSolve(A,x,x).
3288: Notes:
3289: Most users should usually employ the simplified KSP interface for linear solvers
3290: instead of working directly with matrix algebra routines such as this.
3291: See, e.g., KSPCreate(). However KSP can only solve for one vector (column of X)
3292: at a time.
3294: When using SuperLU_Dist as a parallel solver PETSc will use the SuperLU_Dist functionality to solve multiple right hand sides simultaneously. For MUMPS
3295: it calls a separate solve for each right hand side since MUMPS does not yet support distributed right hand sides.
3297: Since the resulting matrix X must always be dense we do not support sparse representation of the matrix B.
3299: Level: developer
3301: Concepts: matrices^triangular solves
3303: .seealso: MatMatSolveAdd(), MatMatSolveTranspose(), MatMatSolveTransposeAdd(), MatLUFactor(), MatCholeskyFactor()
3304: @*/
3305: PetscErrorCode MatMatSolve(Mat A,Mat B,Mat X)
3306: {
3316: if (X == B) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_IDN,"X and B must be different matrices");
3317: if (!A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3318: 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);
3319: 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);
3320: 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);
3321: 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");
3322: if (!A->rmap->N && !A->cmap->N) return(0);
3323: MatCheckPreallocated(A,1);
3325: PetscLogEventBegin(MAT_MatSolve,A,B,X,0);
3326: if (!A->ops->matsolve) {
3327: PetscInfo1(A,"Mat type %s using basic MatMatSolve\n",((PetscObject)A)->type_name);
3328: MatMatSolve_Basic(A,B,X);
3329: } else {
3330: (*A->ops->matsolve)(A,B,X);
3331: }
3332: PetscLogEventEnd(MAT_MatSolve,A,B,X,0);
3333: PetscObjectStateIncrease((PetscObject)X);
3334: return(0);
3335: }
3340: /*@
3341: MatForwardSolve - Solves L x = b, given a factored matrix, A = LU, or
3342: U^T*D^(1/2) x = b, given a factored symmetric matrix, A = U^T*D*U,
3344: Neighbor-wise Collective on Mat and Vec
3346: Input Parameters:
3347: + mat - the factored matrix
3348: - b - the right-hand-side vector
3350: Output Parameter:
3351: . x - the result vector
3353: Notes:
3354: MatSolve() should be used for most applications, as it performs
3355: a forward solve followed by a backward solve.
3357: The vectors b and x cannot be the same, i.e., one cannot
3358: call MatForwardSolve(A,x,x).
3360: For matrix in seqsbaij format with block size larger than 1,
3361: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3362: MatForwardSolve() solves U^T*D y = b, and
3363: MatBackwardSolve() solves U x = y.
3364: Thus they do not provide a symmetric preconditioner.
3366: Most users should employ the simplified KSP interface for linear solvers
3367: instead of working directly with matrix algebra routines such as this.
3368: See, e.g., KSPCreate().
3370: Level: developer
3372: Concepts: matrices^forward solves
3374: .seealso: MatSolve(), MatBackwardSolve()
3375: @*/
3376: PetscErrorCode MatForwardSolve(Mat mat,Vec b,Vec x)
3377: {
3387: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3388: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3389: if (!mat->ops->forwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3390: 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);
3391: 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);
3392: 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);
3393: MatCheckPreallocated(mat,1);
3394: PetscLogEventBegin(MAT_ForwardSolve,mat,b,x,0);
3395: (*mat->ops->forwardsolve)(mat,b,x);
3396: PetscLogEventEnd(MAT_ForwardSolve,mat,b,x,0);
3397: PetscObjectStateIncrease((PetscObject)x);
3398: return(0);
3399: }
3403: /*@
3404: MatBackwardSolve - Solves U x = b, given a factored matrix, A = LU.
3405: D^(1/2) U x = b, given a factored symmetric matrix, A = U^T*D*U,
3407: Neighbor-wise Collective on Mat and Vec
3409: Input Parameters:
3410: + mat - the factored matrix
3411: - b - the right-hand-side vector
3413: Output Parameter:
3414: . x - the result vector
3416: Notes:
3417: MatSolve() should be used for most applications, as it performs
3418: a forward solve followed by a backward solve.
3420: The vectors b and x cannot be the same. I.e., one cannot
3421: call MatBackwardSolve(A,x,x).
3423: For matrix in seqsbaij format with block size larger than 1,
3424: the diagonal blocks are not implemented as D = D^(1/2) * D^(1/2) yet.
3425: MatForwardSolve() solves U^T*D y = b, and
3426: MatBackwardSolve() solves U x = y.
3427: Thus they do not provide a symmetric preconditioner.
3429: Most users should employ the simplified KSP interface for linear solvers
3430: instead of working directly with matrix algebra routines such as this.
3431: See, e.g., KSPCreate().
3433: Level: developer
3435: Concepts: matrices^backward solves
3437: .seealso: MatSolve(), MatForwardSolve()
3438: @*/
3439: PetscErrorCode MatBackwardSolve(Mat mat,Vec b,Vec x)
3440: {
3450: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3451: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3452: if (!mat->ops->backwardsolve) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3453: 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);
3454: 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);
3455: 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);
3456: MatCheckPreallocated(mat,1);
3458: PetscLogEventBegin(MAT_BackwardSolve,mat,b,x,0);
3459: (*mat->ops->backwardsolve)(mat,b,x);
3460: PetscLogEventEnd(MAT_BackwardSolve,mat,b,x,0);
3461: PetscObjectStateIncrease((PetscObject)x);
3462: return(0);
3463: }
3467: /*@
3468: MatSolveAdd - Computes x = y + inv(A)*b, given a factored matrix.
3470: Neighbor-wise Collective on Mat and Vec
3472: Input Parameters:
3473: + mat - the factored matrix
3474: . b - the right-hand-side vector
3475: - y - the vector to be added to
3477: Output Parameter:
3478: . x - the result vector
3480: Notes:
3481: The vectors b and x cannot be the same. I.e., one cannot
3482: call MatSolveAdd(A,x,y,x).
3484: Most users should employ the simplified KSP interface for linear solvers
3485: instead of working directly with matrix algebra routines such as this.
3486: See, e.g., KSPCreate().
3488: Level: developer
3490: Concepts: matrices^triangular solves
3492: .seealso: MatSolve(), MatSolveTranspose(), MatSolveTransposeAdd()
3493: @*/
3494: PetscErrorCode MatSolveAdd(Mat mat,Vec b,Vec y,Vec x)
3495: {
3496: PetscScalar one = 1.0;
3497: Vec tmp;
3509: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3510: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3511: 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);
3512: 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);
3513: 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);
3514: 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);
3515: 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);
3516: MatCheckPreallocated(mat,1);
3518: PetscLogEventBegin(MAT_SolveAdd,mat,b,x,y);
3519: if (mat->ops->solveadd) {
3520: (*mat->ops->solveadd)(mat,b,y,x);
3521: } else {
3522: /* do the solve then the add manually */
3523: if (x != y) {
3524: MatSolve(mat,b,x);
3525: VecAXPY(x,one,y);
3526: } else {
3527: VecDuplicate(x,&tmp);
3528: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3529: VecCopy(x,tmp);
3530: MatSolve(mat,b,x);
3531: VecAXPY(x,one,tmp);
3532: VecDestroy(&tmp);
3533: }
3534: }
3535: PetscLogEventEnd(MAT_SolveAdd,mat,b,x,y);
3536: PetscObjectStateIncrease((PetscObject)x);
3537: return(0);
3538: }
3542: /*@
3543: MatSolveTranspose - Solves A' x = b, given a factored matrix.
3545: Neighbor-wise Collective on Mat and Vec
3547: Input Parameters:
3548: + mat - the factored matrix
3549: - b - the right-hand-side vector
3551: Output Parameter:
3552: . x - the result vector
3554: Notes:
3555: The vectors b and x cannot be the same. I.e., one cannot
3556: call MatSolveTranspose(A,x,x).
3558: Most users should employ the simplified KSP interface for linear solvers
3559: instead of working directly with matrix algebra routines such as this.
3560: See, e.g., KSPCreate().
3562: Level: developer
3564: Concepts: matrices^triangular solves
3566: .seealso: MatSolve(), MatSolveAdd(), MatSolveTransposeAdd()
3567: @*/
3568: PetscErrorCode MatSolveTranspose(Mat mat,Vec b,Vec x)
3569: {
3579: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3580: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3581: if (!mat->ops->solvetranspose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s",((PetscObject)mat)->type_name);
3582: 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);
3583: 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);
3584: MatCheckPreallocated(mat,1);
3585: PetscLogEventBegin(MAT_SolveTranspose,mat,b,x,0);
3586: if (mat->errortype) {
3587: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3588: VecSetInf(x);
3589: } else {
3590: (*mat->ops->solvetranspose)(mat,b,x);
3591: }
3592: PetscLogEventEnd(MAT_SolveTranspose,mat,b,x,0);
3593: PetscObjectStateIncrease((PetscObject)x);
3594: return(0);
3595: }
3599: /*@
3600: MatSolveTransposeAdd - Computes x = y + inv(Transpose(A)) b, given a
3601: factored matrix.
3603: Neighbor-wise Collective on Mat and Vec
3605: Input Parameters:
3606: + mat - the factored matrix
3607: . b - the right-hand-side vector
3608: - y - the vector to be added to
3610: Output Parameter:
3611: . x - the result vector
3613: Notes:
3614: The vectors b and x cannot be the same. I.e., one cannot
3615: call MatSolveTransposeAdd(A,x,y,x).
3617: Most users should employ the simplified KSP interface for linear solvers
3618: instead of working directly with matrix algebra routines such as this.
3619: See, e.g., KSPCreate().
3621: Level: developer
3623: Concepts: matrices^triangular solves
3625: .seealso: MatSolve(), MatSolveAdd(), MatSolveTranspose()
3626: @*/
3627: PetscErrorCode MatSolveTransposeAdd(Mat mat,Vec b,Vec y,Vec x)
3628: {
3629: PetscScalar one = 1.0;
3631: Vec tmp;
3642: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
3643: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
3644: 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);
3645: 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);
3646: 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);
3647: 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);
3648: MatCheckPreallocated(mat,1);
3650: PetscLogEventBegin(MAT_SolveTransposeAdd,mat,b,x,y);
3651: if (mat->ops->solvetransposeadd) {
3652: if (mat->errortype) {
3653: PetscInfo1(mat,"MatFactorError %D\n",mat->errortype);
3654: VecSetInf(x);
3655: } else {
3656: (*mat->ops->solvetransposeadd)(mat,b,y,x);
3657: }
3658: } else {
3659: /* do the solve then the add manually */
3660: if (x != y) {
3661: MatSolveTranspose(mat,b,x);
3662: VecAXPY(x,one,y);
3663: } else {
3664: VecDuplicate(x,&tmp);
3665: PetscLogObjectParent((PetscObject)mat,(PetscObject)tmp);
3666: VecCopy(x,tmp);
3667: MatSolveTranspose(mat,b,x);
3668: VecAXPY(x,one,tmp);
3669: VecDestroy(&tmp);
3670: }
3671: }
3672: PetscLogEventEnd(MAT_SolveTransposeAdd,mat,b,x,y);
3673: PetscObjectStateIncrease((PetscObject)x);
3674: return(0);
3675: }
3676: /* ----------------------------------------------------------------*/
3680: /*@
3681: MatSOR - Computes relaxation (SOR, Gauss-Seidel) sweeps.
3683: Neighbor-wise Collective on Mat and Vec
3685: Input Parameters:
3686: + mat - the matrix
3687: . b - the right hand side
3688: . omega - the relaxation factor
3689: . flag - flag indicating the type of SOR (see below)
3690: . shift - diagonal shift
3691: . its - the number of iterations
3692: - lits - the number of local iterations
3694: Output Parameters:
3695: . x - the solution (can contain an initial guess, use option SOR_ZERO_INITIAL_GUESS to indicate no guess)
3697: SOR Flags:
3698: . SOR_FORWARD_SWEEP - forward SOR
3699: . SOR_BACKWARD_SWEEP - backward SOR
3700: . SOR_SYMMETRIC_SWEEP - SSOR (symmetric SOR)
3701: . SOR_LOCAL_FORWARD_SWEEP - local forward SOR
3702: . SOR_LOCAL_BACKWARD_SWEEP - local forward SOR
3703: . SOR_LOCAL_SYMMETRIC_SWEEP - local SSOR
3704: . SOR_APPLY_UPPER, SOR_APPLY_LOWER - applies
3705: upper/lower triangular part of matrix to
3706: vector (with omega)
3707: . SOR_ZERO_INITIAL_GUESS - zero initial guess
3709: Notes:
3710: SOR_LOCAL_FORWARD_SWEEP, SOR_LOCAL_BACKWARD_SWEEP, and
3711: SOR_LOCAL_SYMMETRIC_SWEEP perform separate independent smoothings
3712: on each processor.
3714: Application programmers will not generally use MatSOR() directly,
3715: but instead will employ the KSP/PC interface.
3717: Notes: for BAIJ, SBAIJ, and AIJ matrices with Inodes this does a block SOR smoothing, otherwise it does a pointwise smoothing
3719: Notes for Advanced Users:
3720: The flags are implemented as bitwise inclusive or operations.
3721: For example, use (SOR_ZERO_INITIAL_GUESS | SOR_SYMMETRIC_SWEEP)
3722: to specify a zero initial guess for SSOR.
3724: Most users should employ the simplified KSP interface for linear solvers
3725: instead of working directly with matrix algebra routines such as this.
3726: See, e.g., KSPCreate().
3728: Vectors x and b CANNOT be the same
3730: Developer Note: We should add block SOR support for AIJ matrices with block size set to great than one and no inodes
3732: Level: developer
3734: Concepts: matrices^relaxation
3735: Concepts: matrices^SOR
3736: Concepts: matrices^Gauss-Seidel
3738: @*/
3739: PetscErrorCode MatSOR(Mat mat,Vec b,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec x)
3740: {
3750: if (!mat->ops->sor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
3751: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3752: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3753: 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);
3754: 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);
3755: 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);
3756: if (its <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D positive",its);
3757: if (lits <= 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires local its %D positive",lits);
3758: if (b == x) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"b and x vector cannot be the same");
3760: MatCheckPreallocated(mat,1);
3761: PetscLogEventBegin(MAT_SOR,mat,b,x,0);
3762: ierr =(*mat->ops->sor)(mat,b,omega,flag,shift,its,lits,x);
3763: PetscLogEventEnd(MAT_SOR,mat,b,x,0);
3764: PetscObjectStateIncrease((PetscObject)x);
3765: return(0);
3766: }
3770: /*
3771: Default matrix copy routine.
3772: */
3773: PetscErrorCode MatCopy_Basic(Mat A,Mat B,MatStructure str)
3774: {
3775: PetscErrorCode ierr;
3776: PetscInt i,rstart = 0,rend = 0,nz;
3777: const PetscInt *cwork;
3778: const PetscScalar *vwork;
3781: if (B->assembled) {
3782: MatZeroEntries(B);
3783: }
3784: MatGetOwnershipRange(A,&rstart,&rend);
3785: for (i=rstart; i<rend; i++) {
3786: MatGetRow(A,i,&nz,&cwork,&vwork);
3787: MatSetValues(B,1,&i,nz,cwork,vwork,INSERT_VALUES);
3788: MatRestoreRow(A,i,&nz,&cwork,&vwork);
3789: }
3790: MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
3791: MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
3792: PetscObjectStateIncrease((PetscObject)B);
3793: return(0);
3794: }
3798: /*@
3799: MatCopy - Copys a matrix to another matrix.
3801: Collective on Mat
3803: Input Parameters:
3804: + A - the matrix
3805: - str - SAME_NONZERO_PATTERN or DIFFERENT_NONZERO_PATTERN
3807: Output Parameter:
3808: . B - where the copy is put
3810: Notes:
3811: If you use SAME_NONZERO_PATTERN then the two matrices had better have the
3812: same nonzero pattern or the routine will crash.
3814: MatCopy() copies the matrix entries of a matrix to another existing
3815: matrix (after first zeroing the second matrix). A related routine is
3816: MatConvert(), which first creates a new matrix and then copies the data.
3818: Level: intermediate
3820: Concepts: matrices^copying
3822: .seealso: MatConvert(), MatDuplicate()
3824: @*/
3825: PetscErrorCode MatCopy(Mat A,Mat B,MatStructure str)
3826: {
3828: PetscInt i;
3836: MatCheckPreallocated(B,2);
3837: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3838: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3839: 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);
3840: MatCheckPreallocated(A,1);
3842: PetscLogEventBegin(MAT_Copy,A,B,0,0);
3843: if (A->ops->copy) {
3844: (*A->ops->copy)(A,B,str);
3845: } else { /* generic conversion */
3846: MatCopy_Basic(A,B,str);
3847: }
3849: B->stencil.dim = A->stencil.dim;
3850: B->stencil.noc = A->stencil.noc;
3851: for (i=0; i<=A->stencil.dim; i++) {
3852: B->stencil.dims[i] = A->stencil.dims[i];
3853: B->stencil.starts[i] = A->stencil.starts[i];
3854: }
3856: PetscLogEventEnd(MAT_Copy,A,B,0,0);
3857: PetscObjectStateIncrease((PetscObject)B);
3858: return(0);
3859: }
3863: /*@C
3864: MatConvert - Converts a matrix to another matrix, either of the same
3865: or different type.
3867: Collective on Mat
3869: Input Parameters:
3870: + mat - the matrix
3871: . newtype - new matrix type. Use MATSAME to create a new matrix of the
3872: same type as the original matrix.
3873: - reuse - denotes if the destination matrix is to be created or reused.
3874: Use MAT_INPLACE_MATRIX for inplace conversion, otherwise use
3875: MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX.
3877: Output Parameter:
3878: . M - pointer to place new matrix
3880: Notes:
3881: MatConvert() first creates a new matrix and then copies the data from
3882: the first matrix. A related routine is MatCopy(), which copies the matrix
3883: entries of one matrix to another already existing matrix context.
3885: Cannot be used to convert a sequential matrix to parallel or parallel to sequential,
3886: the MPI communicator of the generated matrix is always the same as the communicator
3887: of the input matrix.
3889: Level: intermediate
3891: Concepts: matrices^converting between storage formats
3893: .seealso: MatCopy(), MatDuplicate()
3894: @*/
3895: PetscErrorCode MatConvert(Mat mat, MatType newtype,MatReuse reuse,Mat *M)
3896: {
3898: PetscBool sametype,issame,flg;
3899: char convname[256],mtype[256];
3900: Mat B;
3906: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
3907: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
3908: MatCheckPreallocated(mat,1);
3909: MatSetOption(mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);
3911: PetscOptionsGetString(((PetscObject)mat)->options,((PetscObject)mat)->prefix,"-matconvert_type",mtype,256,&flg);
3912: if (flg) {
3913: newtype = mtype;
3914: }
3915: PetscObjectTypeCompare((PetscObject)mat,newtype,&sametype);
3916: PetscStrcmp(newtype,"same",&issame);
3917: if ((reuse == MAT_INPLACE_MATRIX) && (mat != *M)) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MAT_INPLACE_MATRIX requires same input and output matrix");
3919: if ((reuse == MAT_INPLACE_MATRIX) && (issame || sametype)) return(0);
3921: if ((sametype || issame) && (reuse==MAT_INITIAL_MATRIX) && mat->ops->duplicate) {
3922: (*mat->ops->duplicate)(mat,MAT_COPY_VALUES,M);
3923: } else {
3924: PetscErrorCode (*conv)(Mat, MatType,MatReuse,Mat*)=NULL;
3925: const char *prefix[3] = {"seq","mpi",""};
3926: PetscInt i;
3927: /*
3928: Order of precedence:
3929: 1) See if a specialized converter is known to the current matrix.
3930: 2) See if a specialized converter is known to the desired matrix class.
3931: 3) See if a good general converter is registered for the desired class
3932: (as of 6/27/03 only MATMPIADJ falls into this category).
3933: 4) See if a good general converter is known for the current matrix.
3934: 5) Use a really basic converter.
3935: */
3937: /* 1) See if a specialized converter is known to the current matrix and the desired class */
3938: for (i=0; i<3; i++) {
3939: PetscStrcpy(convname,"MatConvert_");
3940: PetscStrcat(convname,((PetscObject)mat)->type_name);
3941: PetscStrcat(convname,"_");
3942: PetscStrcat(convname,prefix[i]);
3943: PetscStrcat(convname,issame ? ((PetscObject)mat)->type_name : newtype);
3944: PetscStrcat(convname,"_C");
3945: PetscObjectQueryFunction((PetscObject)mat,convname,&conv);
3946: if (conv) goto foundconv;
3947: }
3949: /* 2) See if a specialized converter is known to the desired matrix class. */
3950: MatCreate(PetscObjectComm((PetscObject)mat),&B);
3951: MatSetSizes(B,mat->rmap->n,mat->cmap->n,mat->rmap->N,mat->cmap->N);
3952: MatSetType(B,newtype);
3953: for (i=0; i<3; i++) {
3954: PetscStrcpy(convname,"MatConvert_");
3955: PetscStrcat(convname,((PetscObject)mat)->type_name);
3956: PetscStrcat(convname,"_");
3957: PetscStrcat(convname,prefix[i]);
3958: PetscStrcat(convname,newtype);
3959: PetscStrcat(convname,"_C");
3960: PetscObjectQueryFunction((PetscObject)B,convname,&conv);
3961: if (conv) {
3962: MatDestroy(&B);
3963: goto foundconv;
3964: }
3965: }
3967: /* 3) See if a good general converter is registered for the desired class */
3968: conv = B->ops->convertfrom;
3969: MatDestroy(&B);
3970: if (conv) goto foundconv;
3972: /* 4) See if a good general converter is known for the current matrix */
3973: if (mat->ops->convert) {
3974: conv = mat->ops->convert;
3975: }
3976: if (conv) goto foundconv;
3978: /* 5) Use a really basic converter. */
3979: conv = MatConvert_Basic;
3981: foundconv:
3982: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
3983: (*conv)(mat,newtype,reuse,M);
3984: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
3985: }
3986: PetscObjectStateIncrease((PetscObject)*M);
3988: /* Copy Mat options */
3989: if (mat->symmetric) {MatSetOption(*M,MAT_SYMMETRIC,PETSC_TRUE);}
3990: if (mat->hermitian) {MatSetOption(*M,MAT_HERMITIAN,PETSC_TRUE);}
3991: return(0);
3992: }
3996: /*@C
3997: MatFactorGetSolverPackage - Returns name of the package providing the factorization routines
3999: Not Collective
4001: Input Parameter:
4002: . mat - the matrix, must be a factored matrix
4004: Output Parameter:
4005: . type - the string name of the package (do not free this string)
4007: Notes:
4008: In Fortran you pass in a empty string and the package name will be copied into it.
4009: (Make sure the string is long enough)
4011: Level: intermediate
4013: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable(), MatGetFactor()
4014: @*/
4015: PetscErrorCode MatFactorGetSolverPackage(Mat mat, const MatSolverPackage *type)
4016: {
4017: PetscErrorCode ierr, (*conv)(Mat,const MatSolverPackage*);
4022: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
4023: PetscObjectQueryFunction((PetscObject)mat,"MatFactorGetSolverPackage_C",&conv);
4024: if (!conv) {
4025: *type = MATSOLVERPETSC;
4026: } else {
4027: (*conv)(mat,type);
4028: }
4029: return(0);
4030: }
4032: typedef struct _MatSolverPackageForSpecifcType* MatSolverPackageForSpecifcType;
4033: struct _MatSolverPackageForSpecifcType {
4034: MatType mtype;
4035: PetscErrorCode (*getfactor[4])(Mat,MatFactorType,Mat*);
4036: MatSolverPackageForSpecifcType next;
4037: };
4039: typedef struct _MatSolverPackageHolder* MatSolverPackageHolder;
4040: struct _MatSolverPackageHolder {
4041: char *name;
4042: MatSolverPackageForSpecifcType handlers;
4043: MatSolverPackageHolder next;
4044: };
4046: static MatSolverPackageHolder MatSolverPackageHolders = NULL;
4050: /*@C
4051: MatSolvePackageRegister - Registers a MatSolverPackage that works for a particular matrix type
4053: Input Parameters:
4054: + package - name of the package, for example petsc or superlu
4055: . mtype - the matrix type that works with this package
4056: . ftype - the type of factorization supported by the package
4057: - getfactor - routine that will create the factored matrix ready to be used
4059: Level: intermediate
4061: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4062: @*/
4063: PetscErrorCode MatSolverPackageRegister(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscErrorCode (*getfactor)(Mat,MatFactorType,Mat*))
4064: {
4065: PetscErrorCode ierr;
4066: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4067: PetscBool flg;
4068: MatSolverPackageForSpecifcType inext,iprev = NULL;
4071: if (!next) {
4072: PetscNew(&MatSolverPackageHolders);
4073: PetscStrallocpy(package,&MatSolverPackageHolders->name);
4074: PetscNew(&MatSolverPackageHolders->handlers);
4075: PetscStrallocpy(mtype,(char **)&MatSolverPackageHolders->handlers->mtype);
4076: MatSolverPackageHolders->handlers->getfactor[(int)ftype-1] = getfactor;
4077: return(0);
4078: }
4079: while (next) {
4080: PetscStrcasecmp(package,next->name,&flg);
4081: if (flg) {
4082: inext = next->handlers;
4083: while (inext) {
4084: PetscStrcasecmp(mtype,inext->mtype,&flg);
4085: if (flg) {
4086: inext->getfactor[(int)ftype-1] = getfactor;
4087: return(0);
4088: }
4089: iprev = inext;
4090: inext = inext->next;
4091: }
4092: PetscNew(&iprev->next);
4093: PetscStrallocpy(mtype,(char **)&iprev->next->mtype);
4094: iprev->next->getfactor[(int)ftype-1] = getfactor;
4095: return(0);
4096: }
4097: prev = next;
4098: next = next->next;
4099: }
4100: PetscNew(&prev->next);
4101: PetscStrallocpy(package,&prev->next->name);
4102: PetscNew(&prev->next->handlers);
4103: PetscStrallocpy(mtype,(char **)&prev->next->handlers->mtype);
4104: prev->next->handlers->getfactor[(int)ftype-1] = getfactor;
4105: return(0);
4106: }
4110: /*@C
4111: MatSolvePackageGet - Get's the function that creates the factor matrix if it exist
4113: Input Parameters:
4114: + package - name of the package, for example petsc or superlu
4115: . ftype - the type of factorization supported by the package
4116: - mtype - the matrix type that works with this package
4118: Output Parameters:
4119: + foundpackage - PETSC_TRUE if the package was registered
4120: . foundmtype - PETSC_TRUE if the package supports the requested mtype
4121: - getfactor - routine that will create the factored matrix ready to be used or NULL if not found
4123: Level: intermediate
4125: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4126: @*/
4127: PetscErrorCode MatSolverPackageGet(const MatSolverPackage package,const MatType mtype,MatFactorType ftype,PetscBool *foundpackage,PetscBool *foundmtype,PetscErrorCode (**getfactor)(Mat,MatFactorType,Mat*))
4128: {
4129: PetscErrorCode ierr;
4130: MatSolverPackageHolder next = MatSolverPackageHolders;
4131: PetscBool flg;
4132: MatSolverPackageForSpecifcType inext;
4135: if (foundpackage) *foundpackage = PETSC_FALSE;
4136: if (foundmtype) *foundmtype = PETSC_FALSE;
4137: if (getfactor) *getfactor = NULL;
4139: if (package) {
4140: while (next) {
4141: PetscStrcasecmp(package,next->name,&flg);
4142: if (flg) {
4143: if (foundpackage) *foundpackage = PETSC_TRUE;
4144: inext = next->handlers;
4145: while (inext) {
4146: PetscStrcasecmp(mtype,inext->mtype,&flg);
4147: if (flg) {
4148: if (foundmtype) *foundmtype = PETSC_TRUE;
4149: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4150: return(0);
4151: }
4152: inext = inext->next;
4153: }
4154: }
4155: next = next->next;
4156: }
4157: } else {
4158: while (next) {
4159: inext = next->handlers;
4160: while (inext) {
4161: PetscStrcasecmp(mtype,inext->mtype,&flg);
4162: if (flg && inext->getfactor[(int)ftype-1]) {
4163: if (foundpackage) *foundpackage = PETSC_TRUE;
4164: if (foundmtype) *foundmtype = PETSC_TRUE;
4165: if (getfactor) *getfactor = inext->getfactor[(int)ftype-1];
4166: return(0);
4167: }
4168: inext = inext->next;
4169: }
4170: next = next->next;
4171: }
4172: }
4173: return(0);
4174: }
4178: PetscErrorCode MatSolverPackageDestroy(void)
4179: {
4180: PetscErrorCode ierr;
4181: MatSolverPackageHolder next = MatSolverPackageHolders,prev;
4182: MatSolverPackageForSpecifcType inext,iprev;
4185: while (next) {
4186: PetscFree(next->name);
4187: inext = next->handlers;
4188: while (inext) {
4189: PetscFree(inext->mtype);
4190: iprev = inext;
4191: inext = inext->next;
4192: PetscFree(iprev);
4193: }
4194: prev = next;
4195: next = next->next;
4196: PetscFree(prev);
4197: }
4198: MatSolverPackageHolders = NULL;
4199: return(0);
4200: }
4204: /*@C
4205: MatGetFactor - Returns a matrix suitable to calls to MatXXFactorSymbolic()
4207: Collective on Mat
4209: Input Parameters:
4210: + mat - the matrix
4211: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4212: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4214: Output Parameters:
4215: . f - the factor matrix used with MatXXFactorSymbolic() calls
4217: Notes:
4218: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4219: such as pastix, superlu, mumps etc.
4221: PETSc must have been ./configure to use the external solver, using the option --download-package
4223: Level: intermediate
4225: .seealso: MatCopy(), MatDuplicate(), MatGetFactorAvailable()
4226: @*/
4227: PetscErrorCode MatGetFactor(Mat mat, const MatSolverPackage type,MatFactorType ftype,Mat *f)
4228: {
4229: PetscErrorCode ierr,(*conv)(Mat,MatFactorType,Mat*);
4230: PetscBool foundpackage,foundmtype;
4236: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4237: MatCheckPreallocated(mat,1);
4239: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,&foundpackage,&foundmtype,&conv);
4240: if (!foundpackage) {
4241: if (type) {
4242: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate solver package %s. Perhaps you must ./configure with --download-%s",type,type);
4243: } else {
4244: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"Could not locate a solver package. Perhaps you must ./configure with --download-<package>");
4245: }
4246: }
4247:
4248: if (!foundmtype) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_MISSING_FACTOR,"MatSolverPackage %s does not support matrix type %s",type,((PetscObject)mat)->type_name);
4249: 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);
4251: (*conv)(mat,ftype,f);
4252: return(0);
4253: }
4257: /*@C
4258: MatGetFactorAvailable - Returns a a flag if matrix supports particular package and factor type
4260: Not Collective
4262: Input Parameters:
4263: + mat - the matrix
4264: . type - name of solver type, for example, superlu, petsc (to use PETSc's default)
4265: - ftype - factor type, MAT_FACTOR_LU, MAT_FACTOR_CHOLESKY, MAT_FACTOR_ICC, MAT_FACTOR_ILU,
4267: Output Parameter:
4268: . flg - PETSC_TRUE if the factorization is available
4270: Notes:
4271: Some PETSc matrix formats have alternative solvers available that are contained in alternative packages
4272: such as pastix, superlu, mumps etc.
4274: PETSc must have been ./configure to use the external solver, using the option --download-package
4276: Level: intermediate
4278: .seealso: MatCopy(), MatDuplicate(), MatGetFactor()
4279: @*/
4280: PetscErrorCode MatGetFactorAvailable(Mat mat, const MatSolverPackage type,MatFactorType ftype,PetscBool *flg)
4281: {
4282: PetscErrorCode ierr, (*gconv)(Mat,MatFactorType,Mat*);
4288: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4289: MatCheckPreallocated(mat,1);
4291: *flg = PETSC_FALSE;
4292: MatSolverPackageGet(type,((PetscObject)mat)->type_name,ftype,NULL,NULL,&gconv);
4293: if (gconv) {
4294: *flg = PETSC_TRUE;
4295: }
4296: return(0);
4297: }
4299: #include <petscdmtypes.h>
4303: /*@
4304: MatDuplicate - Duplicates a matrix including the non-zero structure.
4306: Collective on Mat
4308: Input Parameters:
4309: + mat - the matrix
4310: - op - either MAT_DO_NOT_COPY_VALUES or MAT_COPY_VALUES, cause it to copy the numerical values in the matrix
4311: MAT_SHARE_NONZERO_PATTERN to share the nonzero patterns with the previous matrix and not copy them.
4313: Output Parameter:
4314: . M - pointer to place new matrix
4316: Level: intermediate
4318: Concepts: matrices^duplicating
4320: Notes: You cannot change the nonzero pattern for the parent or child matrix if you use MAT_SHARE_NONZERO_PATTERN.
4322: .seealso: MatCopy(), MatConvert()
4323: @*/
4324: PetscErrorCode MatDuplicate(Mat mat,MatDuplicateOption op,Mat *M)
4325: {
4327: Mat B;
4328: PetscInt i;
4329: DM dm;
4335: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4336: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4337: MatCheckPreallocated(mat,1);
4339: *M = 0;
4340: if (!mat->ops->duplicate) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not written for this matrix type");
4341: PetscLogEventBegin(MAT_Convert,mat,0,0,0);
4342: (*mat->ops->duplicate)(mat,op,M);
4343: B = *M;
4345: B->stencil.dim = mat->stencil.dim;
4346: B->stencil.noc = mat->stencil.noc;
4347: for (i=0; i<=mat->stencil.dim; i++) {
4348: B->stencil.dims[i] = mat->stencil.dims[i];
4349: B->stencil.starts[i] = mat->stencil.starts[i];
4350: }
4352: B->nooffproczerorows = mat->nooffproczerorows;
4353: B->nooffprocentries = mat->nooffprocentries;
4355: PetscObjectQuery((PetscObject) mat, "__PETSc_dm", (PetscObject*) &dm);
4356: if (dm) {
4357: PetscObjectCompose((PetscObject) B, "__PETSc_dm", (PetscObject) dm);
4358: }
4359: PetscLogEventEnd(MAT_Convert,mat,0,0,0);
4360: PetscObjectStateIncrease((PetscObject)B);
4361: return(0);
4362: }
4366: /*@
4367: MatGetDiagonal - Gets the diagonal of a matrix.
4369: Logically Collective on Mat and Vec
4371: Input Parameters:
4372: + mat - the matrix
4373: - v - the vector for storing the diagonal
4375: Output Parameter:
4376: . v - the diagonal of the matrix
4378: Level: intermediate
4380: Note:
4381: Currently only correct in parallel for square matrices.
4383: Concepts: matrices^accessing diagonals
4385: .seealso: MatGetRow(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs()
4386: @*/
4387: PetscErrorCode MatGetDiagonal(Mat mat,Vec v)
4388: {
4395: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4396: if (!mat->ops->getdiagonal) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4397: MatCheckPreallocated(mat,1);
4399: (*mat->ops->getdiagonal)(mat,v);
4400: PetscObjectStateIncrease((PetscObject)v);
4401: return(0);
4402: }
4406: /*@C
4407: MatGetRowMin - Gets the minimum value (of the real part) of each
4408: row of the matrix
4410: Logically Collective on Mat and Vec
4412: Input Parameters:
4413: . mat - the matrix
4415: Output Parameter:
4416: + v - the vector for storing the maximums
4417: - idx - the indices of the column found for each row (optional)
4419: Level: intermediate
4421: Notes: The result of this call are the same as if one converted the matrix to dense format
4422: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4424: This code is only implemented for a couple of matrix formats.
4426: Concepts: matrices^getting row maximums
4428: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(),
4429: MatGetRowMax()
4430: @*/
4431: PetscErrorCode MatGetRowMin(Mat mat,Vec v,PetscInt idx[])
4432: {
4439: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4440: if (!mat->ops->getrowmax) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4441: MatCheckPreallocated(mat,1);
4443: (*mat->ops->getrowmin)(mat,v,idx);
4444: PetscObjectStateIncrease((PetscObject)v);
4445: return(0);
4446: }
4450: /*@C
4451: MatGetRowMinAbs - Gets the minimum value (in absolute value) of each
4452: row of the matrix
4454: Logically Collective on Mat and Vec
4456: Input Parameters:
4457: . mat - the matrix
4459: Output Parameter:
4460: + v - the vector for storing the minimums
4461: - idx - the indices of the column found for each row (or NULL if not needed)
4463: Level: intermediate
4465: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4466: row is 0 (the first column).
4468: This code is only implemented for a couple of matrix formats.
4470: Concepts: matrices^getting row maximums
4472: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMaxAbs(), MatGetRowMin()
4473: @*/
4474: PetscErrorCode MatGetRowMinAbs(Mat mat,Vec v,PetscInt idx[])
4475: {
4482: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4483: if (!mat->ops->getrowminabs) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4484: MatCheckPreallocated(mat,1);
4485: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4487: (*mat->ops->getrowminabs)(mat,v,idx);
4488: PetscObjectStateIncrease((PetscObject)v);
4489: return(0);
4490: }
4494: /*@C
4495: MatGetRowMax - Gets the maximum value (of the real part) of each
4496: row of the matrix
4498: Logically Collective on Mat and Vec
4500: Input Parameters:
4501: . mat - the matrix
4503: Output Parameter:
4504: + v - the vector for storing the maximums
4505: - idx - the indices of the column found for each row (optional)
4507: Level: intermediate
4509: Notes: The result of this call are the same as if one converted the matrix to dense format
4510: and found the minimum value in each row (i.e. the implicit zeros are counted as zeros).
4512: This code is only implemented for a couple of matrix formats.
4514: Concepts: matrices^getting row maximums
4516: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMaxAbs(), MatGetRowMin()
4517: @*/
4518: PetscErrorCode MatGetRowMax(Mat mat,Vec v,PetscInt idx[])
4519: {
4526: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4527: if (!mat->ops->getrowmax) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4528: MatCheckPreallocated(mat,1);
4530: (*mat->ops->getrowmax)(mat,v,idx);
4531: PetscObjectStateIncrease((PetscObject)v);
4532: return(0);
4533: }
4537: /*@C
4538: MatGetRowMaxAbs - Gets the maximum value (in absolute value) of each
4539: row of the matrix
4541: Logically Collective on Mat and Vec
4543: Input Parameters:
4544: . mat - the matrix
4546: Output Parameter:
4547: + v - the vector for storing the maximums
4548: - idx - the indices of the column found for each row (or NULL if not needed)
4550: Level: intermediate
4552: Notes: if a row is completely empty or has only 0.0 values then the idx[] value for that
4553: row is 0 (the first column).
4555: This code is only implemented for a couple of matrix formats.
4557: Concepts: matrices^getting row maximums
4559: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4560: @*/
4561: PetscErrorCode MatGetRowMaxAbs(Mat mat,Vec v,PetscInt idx[])
4562: {
4569: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4570: if (!mat->ops->getrowmaxabs) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4571: MatCheckPreallocated(mat,1);
4572: if (idx) {PetscMemzero(idx,mat->rmap->n*sizeof(PetscInt));}
4574: (*mat->ops->getrowmaxabs)(mat,v,idx);
4575: PetscObjectStateIncrease((PetscObject)v);
4576: return(0);
4577: }
4581: /*@
4582: MatGetRowSum - Gets the sum of each row of the matrix
4584: Logically Collective on Mat and Vec
4586: Input Parameters:
4587: . mat - the matrix
4589: Output Parameter:
4590: . v - the vector for storing the sum of rows
4592: Level: intermediate
4594: Notes: This code is slow since it is not currently specialized for different formats
4596: Concepts: matrices^getting row sums
4598: .seealso: MatGetDiagonal(), MatGetSubMatrices(), MatGetSubmatrix(), MatGetRowMax(), MatGetRowMin()
4599: @*/
4600: PetscErrorCode MatGetRowSum(Mat mat, Vec v)
4601: {
4602: PetscInt start = 0, end = 0, row;
4603: PetscScalar *array;
4610: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4611: MatCheckPreallocated(mat,1);
4612: MatGetOwnershipRange(mat, &start, &end);
4613: VecGetArray(v, &array);
4614: for (row = start; row < end; ++row) {
4615: PetscInt ncols, col;
4616: const PetscInt *cols;
4617: const PetscScalar *vals;
4619: array[row - start] = 0.0;
4621: MatGetRow(mat, row, &ncols, &cols, &vals);
4622: for (col = 0; col < ncols; col++) {
4623: array[row - start] += vals[col];
4624: }
4625: MatRestoreRow(mat, row, &ncols, &cols, &vals);
4626: }
4627: VecRestoreArray(v, &array);
4628: PetscObjectStateIncrease((PetscObject) v);
4629: return(0);
4630: }
4634: /*@
4635: MatTranspose - Computes an in-place or out-of-place transpose of a matrix.
4637: Collective on Mat
4639: Input Parameter:
4640: + mat - the matrix to transpose
4641: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
4643: Output Parameters:
4644: . B - the transpose
4646: Notes:
4647: If you pass in &mat for B the transpose will be done in place, for example MatTranspose(mat,MAT_REUSE_MATRIX,&mat);
4649: Consider using MatCreateTranspose() instead if you only need a matrix that behaves like the transpose, but don't need the storage to be changed.
4651: Level: intermediate
4653: Concepts: matrices^transposing
4655: .seealso: MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4656: @*/
4657: PetscErrorCode MatTranspose(Mat mat,MatReuse reuse,Mat *B)
4658: {
4664: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4665: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4666: if (!mat->ops->transpose) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4667: MatCheckPreallocated(mat,1);
4669: PetscLogEventBegin(MAT_Transpose,mat,0,0,0);
4670: (*mat->ops->transpose)(mat,reuse,B);
4671: PetscLogEventEnd(MAT_Transpose,mat,0,0,0);
4672: if (B) {PetscObjectStateIncrease((PetscObject)*B);}
4673: return(0);
4674: }
4678: /*@
4679: MatIsTranspose - Test whether a matrix is another one's transpose,
4680: or its own, in which case it tests symmetry.
4682: Collective on Mat
4684: Input Parameter:
4685: + A - the matrix to test
4686: - B - the matrix to test against, this can equal the first parameter
4688: Output Parameters:
4689: . flg - the result
4691: Notes:
4692: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4693: has a running time of the order of the number of nonzeros; the parallel
4694: test involves parallel copies of the block-offdiagonal parts of the matrix.
4696: Level: intermediate
4698: Concepts: matrices^transposing, matrix^symmetry
4700: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian()
4701: @*/
4702: PetscErrorCode MatIsTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4703: {
4704: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4710: PetscObjectQueryFunction((PetscObject)A,"MatIsTranspose_C",&f);
4711: PetscObjectQueryFunction((PetscObject)B,"MatIsTranspose_C",&g);
4712: *flg = PETSC_FALSE;
4713: if (f && g) {
4714: if (f == g) {
4715: (*f)(A,B,tol,flg);
4716: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for symmetry test");
4717: } else {
4718: MatType mattype;
4719: if (!f) {
4720: MatGetType(A,&mattype);
4721: } else {
4722: MatGetType(B,&mattype);
4723: }
4724: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for transpose",mattype);
4725: }
4726: return(0);
4727: }
4731: /*@
4732: MatHermitianTranspose - Computes an in-place or out-of-place transpose of a matrix in complex conjugate.
4734: Collective on Mat
4736: Input Parameter:
4737: + mat - the matrix to transpose and complex conjugate
4738: - reuse - store the transpose matrix in the provided B
4740: Output Parameters:
4741: . B - the Hermitian
4743: Notes:
4744: If you pass in &mat for B the Hermitian will be done in place
4746: Level: intermediate
4748: Concepts: matrices^transposing, complex conjugatex
4750: .seealso: MatTranspose(), MatMultTranspose(), MatMultTransposeAdd(), MatIsTranspose(), MatReuse
4751: @*/
4752: PetscErrorCode MatHermitianTranspose(Mat mat,MatReuse reuse,Mat *B)
4753: {
4757: MatTranspose(mat,reuse,B);
4758: #if defined(PETSC_USE_COMPLEX)
4759: MatConjugate(*B);
4760: #endif
4761: return(0);
4762: }
4766: /*@
4767: MatIsHermitianTranspose - Test whether a matrix is another one's Hermitian transpose,
4769: Collective on Mat
4771: Input Parameter:
4772: + A - the matrix to test
4773: - B - the matrix to test against, this can equal the first parameter
4775: Output Parameters:
4776: . flg - the result
4778: Notes:
4779: Only available for SeqAIJ/MPIAIJ matrices. The sequential algorithm
4780: has a running time of the order of the number of nonzeros; the parallel
4781: test involves parallel copies of the block-offdiagonal parts of the matrix.
4783: Level: intermediate
4785: Concepts: matrices^transposing, matrix^symmetry
4787: .seealso: MatTranspose(), MatIsSymmetric(), MatIsHermitian(), MatIsTranspose()
4788: @*/
4789: PetscErrorCode MatIsHermitianTranspose(Mat A,Mat B,PetscReal tol,PetscBool *flg)
4790: {
4791: PetscErrorCode ierr,(*f)(Mat,Mat,PetscReal,PetscBool*),(*g)(Mat,Mat,PetscReal,PetscBool*);
4797: PetscObjectQueryFunction((PetscObject)A,"MatIsHermitianTranspose_C",&f);
4798: PetscObjectQueryFunction((PetscObject)B,"MatIsHermitianTranspose_C",&g);
4799: if (f && g) {
4800: if (f==g) {
4801: (*f)(A,B,tol,flg);
4802: } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_NOTSAMETYPE,"Matrices do not have the same comparator for Hermitian test");
4803: }
4804: return(0);
4805: }
4809: /*@
4810: MatPermute - Creates a new matrix with rows and columns permuted from the
4811: original.
4813: Collective on Mat
4815: Input Parameters:
4816: + mat - the matrix to permute
4817: . row - row permutation, each processor supplies only the permutation for its rows
4818: - col - column permutation, each processor supplies only the permutation for its columns
4820: Output Parameters:
4821: . B - the permuted matrix
4823: Level: advanced
4825: Note:
4826: The index sets map from row/col of permuted matrix to row/col of original matrix.
4827: The index sets should be on the same communicator as Mat and have the same local sizes.
4829: Concepts: matrices^permuting
4831: .seealso: MatGetOrdering(), ISAllGather()
4833: @*/
4834: PetscErrorCode MatPermute(Mat mat,IS row,IS col,Mat *B)
4835: {
4844: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4845: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4846: if (!mat->ops->permute) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatPermute not available for Mat type %s",((PetscObject)mat)->type_name);
4847: MatCheckPreallocated(mat,1);
4849: (*mat->ops->permute)(mat,row,col,B);
4850: PetscObjectStateIncrease((PetscObject)*B);
4851: return(0);
4852: }
4856: /*@
4857: MatEqual - Compares two matrices.
4859: Collective on Mat
4861: Input Parameters:
4862: + A - the first matrix
4863: - B - the second matrix
4865: Output Parameter:
4866: . flg - PETSC_TRUE if the matrices are equal; PETSC_FALSE otherwise.
4868: Level: intermediate
4870: Concepts: matrices^equality between
4871: @*/
4872: PetscErrorCode MatEqual(Mat A,Mat B,PetscBool *flg)
4873: {
4883: MatCheckPreallocated(B,2);
4884: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4885: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4886: 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);
4887: if (!A->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)A)->type_name);
4888: if (!B->ops->equal) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Mat type %s",((PetscObject)B)->type_name);
4889: 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);
4890: MatCheckPreallocated(A,1);
4892: (*A->ops->equal)(A,B,flg);
4893: return(0);
4894: }
4898: /*@
4899: MatDiagonalScale - Scales a matrix on the left and right by diagonal
4900: matrices that are stored as vectors. Either of the two scaling
4901: matrices can be NULL.
4903: Collective on Mat
4905: Input Parameters:
4906: + mat - the matrix to be scaled
4907: . l - the left scaling vector (or NULL)
4908: - r - the right scaling vector (or NULL)
4910: Notes:
4911: MatDiagonalScale() computes A = LAR, where
4912: L = a diagonal matrix (stored as a vector), R = a diagonal matrix (stored as a vector)
4913: The L scales the rows of the matrix, the R scales the columns of the matrix.
4915: Level: intermediate
4917: Concepts: matrices^diagonal scaling
4918: Concepts: diagonal scaling of matrices
4920: .seealso: MatScale()
4921: @*/
4922: PetscErrorCode MatDiagonalScale(Mat mat,Vec l,Vec r)
4923: {
4929: if (!mat->ops->diagonalscale) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4932: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4933: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4934: MatCheckPreallocated(mat,1);
4936: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4937: (*mat->ops->diagonalscale)(mat,l,r);
4938: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4939: PetscObjectStateIncrease((PetscObject)mat);
4940: #if defined(PETSC_HAVE_CUSP)
4941: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4942: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4943: }
4944: #elif defined(PETSC_HAVE_VIENNACL)
4945: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
4946: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
4947: }
4948: #elif defined(PETSC_HAVE_VECCUDA)
4949: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
4950: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
4951: }
4952: #endif
4953: return(0);
4954: }
4958: /*@
4959: MatScale - Scales all elements of a matrix by a given number.
4961: Logically Collective on Mat
4963: Input Parameters:
4964: + mat - the matrix to be scaled
4965: - a - the scaling value
4967: Output Parameter:
4968: . mat - the scaled matrix
4970: Level: intermediate
4972: Concepts: matrices^scaling all entries
4974: .seealso: MatDiagonalScale()
4975: @*/
4976: PetscErrorCode MatScale(Mat mat,PetscScalar a)
4977: {
4983: if (a != (PetscScalar)1.0 && !mat->ops->scale) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
4984: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
4985: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
4987: MatCheckPreallocated(mat,1);
4989: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
4990: if (a != (PetscScalar)1.0) {
4991: (*mat->ops->scale)(mat,a);
4992: PetscObjectStateIncrease((PetscObject)mat);
4993: }
4994: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
4995: #if defined(PETSC_HAVE_CUSP)
4996: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
4997: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
4998: }
4999: #elif defined(PETSC_HAVE_VIENNACL)
5000: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5001: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5002: }
5003: #elif defined(PETSC_HAVE_VECCUDA)
5004: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5005: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5006: }
5007: #endif
5008: return(0);
5009: }
5013: /*@
5014: MatNorm - Calculates various norms of a matrix.
5016: Collective on Mat
5018: Input Parameters:
5019: + mat - the matrix
5020: - type - the type of norm, NORM_1, NORM_FROBENIUS, NORM_INFINITY
5022: Output Parameters:
5023: . nrm - the resulting norm
5025: Level: intermediate
5027: Concepts: matrices^norm
5028: Concepts: norm^of matrix
5029: @*/
5030: PetscErrorCode MatNorm(Mat mat,NormType type,PetscReal *nrm)
5031: {
5039: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5040: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5041: if (!mat->ops->norm) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5042: MatCheckPreallocated(mat,1);
5044: (*mat->ops->norm)(mat,type,nrm);
5045: return(0);
5046: }
5048: /*
5049: This variable is used to prevent counting of MatAssemblyBegin() that
5050: are called from within a MatAssemblyEnd().
5051: */
5052: static PetscInt MatAssemblyEnd_InUse = 0;
5055: /*@
5056: MatAssemblyBegin - Begins assembling the matrix. This routine should
5057: be called after completing all calls to MatSetValues().
5059: Collective on Mat
5061: Input Parameters:
5062: + mat - the matrix
5063: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5065: Notes:
5066: MatSetValues() generally caches the values. The matrix is ready to
5067: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5068: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5069: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5070: using the matrix.
5072: ALL processes that share a matrix MUST call MatAssemblyBegin() and MatAssemblyEnd() the SAME NUMBER of times, and each time with the
5073: 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
5074: a global collective operation requring all processes that share the matrix.
5076: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5077: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5078: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5080: Level: beginner
5082: Concepts: matrices^assembling
5084: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssembled()
5085: @*/
5086: PetscErrorCode MatAssemblyBegin(Mat mat,MatAssemblyType type)
5087: {
5093: MatCheckPreallocated(mat,1);
5094: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix.\nDid you forget to call MatSetUnfactored()?");
5095: if (mat->assembled) {
5096: mat->was_assembled = PETSC_TRUE;
5097: mat->assembled = PETSC_FALSE;
5098: }
5099: if (!MatAssemblyEnd_InUse) {
5100: PetscLogEventBegin(MAT_AssemblyBegin,mat,0,0,0);
5101: if (mat->ops->assemblybegin) {(*mat->ops->assemblybegin)(mat,type);}
5102: PetscLogEventEnd(MAT_AssemblyBegin,mat,0,0,0);
5103: } else if (mat->ops->assemblybegin) {
5104: (*mat->ops->assemblybegin)(mat,type);
5105: }
5106: return(0);
5107: }
5111: /*@
5112: MatAssembled - Indicates if a matrix has been assembled and is ready for
5113: use; for example, in matrix-vector product.
5115: Not Collective
5117: Input Parameter:
5118: . mat - the matrix
5120: Output Parameter:
5121: . assembled - PETSC_TRUE or PETSC_FALSE
5123: Level: advanced
5125: Concepts: matrices^assembled?
5127: .seealso: MatAssemblyEnd(), MatSetValues(), MatAssemblyBegin()
5128: @*/
5129: PetscErrorCode MatAssembled(Mat mat,PetscBool *assembled)
5130: {
5135: *assembled = mat->assembled;
5136: return(0);
5137: }
5141: /*@
5142: MatAssemblyEnd - Completes assembling the matrix. This routine should
5143: be called after MatAssemblyBegin().
5145: Collective on Mat
5147: Input Parameters:
5148: + mat - the matrix
5149: - type - type of assembly, either MAT_FLUSH_ASSEMBLY or MAT_FINAL_ASSEMBLY
5151: Options Database Keys:
5152: + -mat_view ::ascii_info - Prints info on matrix at conclusion of MatEndAssembly()
5153: . -mat_view ::ascii_info_detail - Prints more detailed info
5154: . -mat_view - Prints matrix in ASCII format
5155: . -mat_view ::ascii_matlab - Prints matrix in Matlab format
5156: . -mat_view draw - PetscDraws nonzero structure of matrix, using MatView() and PetscDrawOpenX().
5157: . -display <name> - Sets display name (default is host)
5158: . -draw_pause <sec> - Sets number of seconds to pause after display
5159: . -mat_view socket - Sends matrix to socket, can be accessed from Matlab (See Users-Manual: Chapter 11 Using MATLAB with PETSc )
5160: . -viewer_socket_machine <machine> - Machine to use for socket
5161: . -viewer_socket_port <port> - Port number to use for socket
5162: - -mat_view binary:filename[:append] - Save matrix to file in binary format
5164: Notes:
5165: MatSetValues() generally caches the values. The matrix is ready to
5166: use only after MatAssemblyBegin() and MatAssemblyEnd() have been called.
5167: Use MAT_FLUSH_ASSEMBLY when switching between ADD_VALUES and INSERT_VALUES
5168: in MatSetValues(); use MAT_FINAL_ASSEMBLY for the final assembly before
5169: using the matrix.
5171: Space for preallocated nonzeros that is not filled by a call to MatSetValues() or a related routine are compressed
5172: out by assembly. If you intend to use that extra space on a subsequent assembly, be sure to insert explicit zeros
5173: before MAT_FINAL_ASSEMBLY so the space is not compressed out.
5175: Level: beginner
5177: .seealso: MatAssemblyBegin(), MatSetValues(), PetscDrawOpenX(), PetscDrawCreate(), MatView(), MatAssembled(), PetscViewerSocketOpen()
5178: @*/
5179: PetscErrorCode MatAssemblyEnd(Mat mat,MatAssemblyType type)
5180: {
5181: PetscErrorCode ierr;
5182: static PetscInt inassm = 0;
5183: PetscBool flg = PETSC_FALSE;
5189: inassm++;
5190: MatAssemblyEnd_InUse++;
5191: if (MatAssemblyEnd_InUse == 1) { /* Do the logging only the first time through */
5192: PetscLogEventBegin(MAT_AssemblyEnd,mat,0,0,0);
5193: if (mat->ops->assemblyend) {
5194: (*mat->ops->assemblyend)(mat,type);
5195: }
5196: PetscLogEventEnd(MAT_AssemblyEnd,mat,0,0,0);
5197: } else if (mat->ops->assemblyend) {
5198: (*mat->ops->assemblyend)(mat,type);
5199: }
5201: /* Flush assembly is not a true assembly */
5202: if (type != MAT_FLUSH_ASSEMBLY) {
5203: mat->assembled = PETSC_TRUE; mat->num_ass++;
5204: }
5205: mat->insertmode = NOT_SET_VALUES;
5206: MatAssemblyEnd_InUse--;
5207: PetscObjectStateIncrease((PetscObject)mat);
5208: if (!mat->symmetric_eternal) {
5209: mat->symmetric_set = PETSC_FALSE;
5210: mat->hermitian_set = PETSC_FALSE;
5211: mat->structurally_symmetric_set = PETSC_FALSE;
5212: }
5213: #if defined(PETSC_HAVE_CUSP)
5214: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5215: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5216: }
5217: #elif defined(PETSC_HAVE_VIENNACL)
5218: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5219: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5220: }
5221: #elif defined(PETSC_HAVE_VECCUDA)
5222: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5223: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5224: }
5225: #endif
5226: if (inassm == 1 && type != MAT_FLUSH_ASSEMBLY) {
5227: MatViewFromOptions(mat,NULL,"-mat_view");
5229: if (mat->checksymmetryonassembly) {
5230: MatIsSymmetric(mat,mat->checksymmetrytol,&flg);
5231: if (flg) {
5232: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5233: } else {
5234: PetscPrintf(PetscObjectComm((PetscObject)mat),"Matrix is not symmetric (tolerance %g)\n",(double)mat->checksymmetrytol);
5235: }
5236: }
5237: if (mat->nullsp && mat->checknullspaceonassembly) {
5238: MatNullSpaceTest(mat->nullsp,mat,NULL);
5239: }
5240: }
5241: inassm--;
5242: return(0);
5243: }
5247: /*@
5248: MatSetOption - Sets a parameter option for a matrix. Some options
5249: may be specific to certain storage formats. Some options
5250: determine how values will be inserted (or added). Sorted,
5251: row-oriented input will generally assemble the fastest. The default
5252: is row-oriented.
5254: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5256: Input Parameters:
5257: + mat - the matrix
5258: . option - the option, one of those listed below (and possibly others),
5259: - flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5261: Options Describing Matrix Structure:
5262: + MAT_SPD - symmetric positive definite
5263: . MAT_SYMMETRIC - symmetric in terms of both structure and value
5264: . MAT_HERMITIAN - transpose is the complex conjugation
5265: . MAT_STRUCTURALLY_SYMMETRIC - symmetric nonzero structure
5266: - MAT_SYMMETRY_ETERNAL - if you would like the symmetry/Hermitian flag
5267: you set to be kept with all future use of the matrix
5268: including after MatAssemblyBegin/End() which could
5269: potentially change the symmetry structure, i.e. you
5270: KNOW the matrix will ALWAYS have the property you set.
5273: Options For Use with MatSetValues():
5274: Insert a logically dense subblock, which can be
5275: . MAT_ROW_ORIENTED - row-oriented (default)
5277: Note these options reflect the data you pass in with MatSetValues(); it has
5278: nothing to do with how the data is stored internally in the matrix
5279: data structure.
5281: When (re)assembling a matrix, we can restrict the input for
5282: efficiency/debugging purposes. These options include:
5283: + MAT_NEW_NONZERO_LOCATIONS - additional insertions will be allowed if they generate a new nonzero (slow)
5284: . MAT_NEW_DIAGONALS - new diagonals will be allowed (for block diagonal format only)
5285: . MAT_IGNORE_OFF_PROC_ENTRIES - drops off-processor entries
5286: . MAT_NEW_NONZERO_LOCATION_ERR - generates an error for new matrix entry
5287: . MAT_USE_HASH_TABLE - uses a hash table to speed up matrix assembly
5288: . MAT_NO_OFF_PROC_ENTRIES - you know each process will only set values for its own rows, will generate an error if
5289: any process sets values for another process. This avoids all reductions in the MatAssembly routines and thus improves
5290: performance for very large process counts.
5291: - MAT_SUBSET_OFF_PROC_ENTRIES - you know that the first assembly after setting this flag will set a superset
5292: of the off-process entries required for all subsequent assemblies. This avoids a rendezvous step in the MatAssembly
5293: functions, instead sending only neighbor messages.
5295: Notes:
5296: Except for MAT_UNUSED_NONZERO_LOCATION_ERR and MAT_ROW_ORIENTED all processes that share the matrix must pass the same value in flg!
5298: Some options are relevant only for particular matrix types and
5299: are thus ignored by others. Other options are not supported by
5300: certain matrix types and will generate an error message if set.
5302: If using a Fortran 77 module to compute a matrix, one may need to
5303: use the column-oriented option (or convert to the row-oriented
5304: format).
5306: MAT_NEW_NONZERO_LOCATIONS set to PETSC_FALSE indicates that any add or insertion
5307: that would generate a new entry in the nonzero structure is instead
5308: ignored. Thus, if memory has not alredy been allocated for this particular
5309: data, then the insertion is ignored. For dense matrices, in which
5310: the entire array is allocated, no entries are ever ignored.
5311: Set after the first MatAssemblyEnd(). If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5313: MAT_NEW_NONZERO_LOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5314: that would generate a new entry in the nonzero structure instead produces
5315: 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
5317: MAT_NEW_NONZERO_ALLOCATION_ERR set to PETSC_TRUE indicates that any add or insertion
5318: that would generate a new entry that has not been preallocated will
5319: instead produce an error. (Currently supported for AIJ and BAIJ formats
5320: only.) This is a useful flag when debugging matrix memory preallocation.
5321: If this option is set then the MatAssemblyBegin/End() processes has one less global reduction
5323: MAT_IGNORE_OFF_PROC_ENTRIES set to PETSC_TRUE indicates entries destined for
5324: other processors should be dropped, rather than stashed.
5325: This is useful if you know that the "owning" processor is also
5326: always generating the correct matrix entries, so that PETSc need
5327: not transfer duplicate entries generated on another processor.
5329: MAT_USE_HASH_TABLE indicates that a hash table be used to improve the
5330: searches during matrix assembly. When this flag is set, the hash table
5331: is created during the first Matrix Assembly. This hash table is
5332: used the next time through, during MatSetVaules()/MatSetVaulesBlocked()
5333: to improve the searching of indices. MAT_NEW_NONZERO_LOCATIONS flag
5334: should be used with MAT_USE_HASH_TABLE flag. This option is currently
5335: supported by MATMPIBAIJ format only.
5337: MAT_KEEP_NONZERO_PATTERN indicates when MatZeroRows() is called the zeroed entries
5338: are kept in the nonzero structure
5340: MAT_IGNORE_ZERO_ENTRIES - for AIJ/IS matrices this will stop zero values from creating
5341: a zero location in the matrix
5343: MAT_USE_INODES - indicates using inode version of the code - works with AIJ matrix types
5345: MAT_NO_OFF_PROC_ZERO_ROWS - you know each process will only zero its own rows. This avoids all reductions in the
5346: zero row routines and thus improves performance for very large process counts.
5348: MAT_IGNORE_LOWER_TRIANGULAR - For SBAIJ matrices will ignore any insertions you make in the lower triangular
5349: part of the matrix (since they should match the upper triangular part).
5351: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5353: Level: intermediate
5355: Concepts: matrices^setting options
5357: .seealso: MatOption, Mat
5359: @*/
5360: PetscErrorCode MatSetOption(Mat mat,MatOption op,PetscBool flg)
5361: {
5367: if (op > 0) {
5370: }
5372: 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);
5373: 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()");
5375: switch (op) {
5376: case MAT_NO_OFF_PROC_ENTRIES:
5377: mat->nooffprocentries = flg;
5378: return(0);
5379: break;
5380: case MAT_SUBSET_OFF_PROC_ENTRIES:
5381: mat->subsetoffprocentries = flg;
5382: return(0);
5383: case MAT_NO_OFF_PROC_ZERO_ROWS:
5384: mat->nooffproczerorows = flg;
5385: return(0);
5386: break;
5387: case MAT_SPD:
5388: mat->spd_set = PETSC_TRUE;
5389: mat->spd = flg;
5390: if (flg) {
5391: mat->symmetric = PETSC_TRUE;
5392: mat->structurally_symmetric = PETSC_TRUE;
5393: mat->symmetric_set = PETSC_TRUE;
5394: mat->structurally_symmetric_set = PETSC_TRUE;
5395: }
5396: break;
5397: case MAT_SYMMETRIC:
5398: mat->symmetric = flg;
5399: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5400: mat->symmetric_set = PETSC_TRUE;
5401: mat->structurally_symmetric_set = flg;
5402: break;
5403: case MAT_HERMITIAN:
5404: mat->hermitian = flg;
5405: if (flg) mat->structurally_symmetric = PETSC_TRUE;
5406: mat->hermitian_set = PETSC_TRUE;
5407: mat->structurally_symmetric_set = flg;
5408: break;
5409: case MAT_STRUCTURALLY_SYMMETRIC:
5410: mat->structurally_symmetric = flg;
5411: mat->structurally_symmetric_set = PETSC_TRUE;
5412: break;
5413: case MAT_SYMMETRY_ETERNAL:
5414: mat->symmetric_eternal = flg;
5415: break;
5416: default:
5417: break;
5418: }
5419: if (mat->ops->setoption) {
5420: (*mat->ops->setoption)(mat,op,flg);
5421: }
5422: return(0);
5423: }
5427: /*@
5428: MatGetOption - Gets a parameter option that has been set for a matrix.
5430: Logically Collective on Mat for certain operations, such as MAT_SPD, not collective for MAT_ROW_ORIENTED, see MatOption
5432: Input Parameters:
5433: + mat - the matrix
5434: - option - the option, this only responds to certain options, check the code for which ones
5436: Output Parameter:
5437: . flg - turn the option on (PETSC_TRUE) or off (PETSC_FALSE)
5439: Notes: Can only be called after MatSetSizes() and MatSetType() have been set.
5441: Level: intermediate
5443: Concepts: matrices^setting options
5445: .seealso: MatOption, MatSetOption()
5447: @*/
5448: PetscErrorCode MatGetOption(Mat mat,MatOption op,PetscBool *flg)
5449: {
5454: 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);
5455: 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()");
5457: switch (op) {
5458: case MAT_NO_OFF_PROC_ENTRIES:
5459: *flg = mat->nooffprocentries;
5460: break;
5461: case MAT_NO_OFF_PROC_ZERO_ROWS:
5462: *flg = mat->nooffproczerorows;
5463: break;
5464: case MAT_SYMMETRIC:
5465: *flg = mat->symmetric;
5466: break;
5467: case MAT_HERMITIAN:
5468: *flg = mat->hermitian;
5469: break;
5470: case MAT_STRUCTURALLY_SYMMETRIC:
5471: *flg = mat->structurally_symmetric;
5472: break;
5473: case MAT_SYMMETRY_ETERNAL:
5474: *flg = mat->symmetric_eternal;
5475: break;
5476: default:
5477: break;
5478: }
5479: return(0);
5480: }
5484: /*@
5485: MatZeroEntries - Zeros all entries of a matrix. For sparse matrices
5486: this routine retains the old nonzero structure.
5488: Logically Collective on Mat
5490: Input Parameters:
5491: . mat - the matrix
5493: Level: intermediate
5495: 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.
5496: See the Performance chapter of the users manual for information on preallocating matrices.
5498: Concepts: matrices^zeroing
5500: .seealso: MatZeroRows()
5501: @*/
5502: PetscErrorCode MatZeroEntries(Mat mat)
5503: {
5509: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5510: 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");
5511: if (!mat->ops->zeroentries) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5512: MatCheckPreallocated(mat,1);
5514: PetscLogEventBegin(MAT_ZeroEntries,mat,0,0,0);
5515: (*mat->ops->zeroentries)(mat);
5516: PetscLogEventEnd(MAT_ZeroEntries,mat,0,0,0);
5517: PetscObjectStateIncrease((PetscObject)mat);
5518: #if defined(PETSC_HAVE_CUSP)
5519: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5520: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5521: }
5522: #elif defined(PETSC_HAVE_VIENNACL)
5523: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5524: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5525: }
5526: #elif defined(PETSC_HAVE_VECCUDA)
5527: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5528: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5529: }
5530: #endif
5531: return(0);
5532: }
5536: /*@C
5537: MatZeroRowsColumns - Zeros all entries (except possibly the main diagonal)
5538: of a set of rows and columns of a matrix.
5540: Collective on Mat
5542: Input Parameters:
5543: + mat - the matrix
5544: . numRows - the number of rows to remove
5545: . rows - the global row indices
5546: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5547: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5548: - b - optional vector of right hand side, that will be adjusted by provided solution
5550: Notes:
5551: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5553: The user can set a value in the diagonal entry (or for the AIJ and
5554: row formats can optionally remove the main diagonal entry from the
5555: nonzero structure as well, by passing 0.0 as the final argument).
5557: For the parallel case, all processes that share the matrix (i.e.,
5558: those in the communicator used for matrix creation) MUST call this
5559: routine, regardless of whether any rows being zeroed are owned by
5560: them.
5562: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5563: list only rows local to itself).
5565: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5567: Level: intermediate
5569: Concepts: matrices^zeroing rows
5571: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumnsIS()
5572: @*/
5573: PetscErrorCode MatZeroRowsColumns(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5574: {
5581: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5582: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5583: if (!mat->ops->zerorowscolumns) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5584: MatCheckPreallocated(mat,1);
5586: (*mat->ops->zerorowscolumns)(mat,numRows,rows,diag,x,b);
5587: MatViewFromOptions(mat,NULL,"-mat_view");
5588: PetscObjectStateIncrease((PetscObject)mat);
5589: #if defined(PETSC_HAVE_CUSP)
5590: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5591: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5592: }
5593: #elif defined(PETSC_HAVE_VIENNACL)
5594: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5595: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5596: }
5597: #elif defined(PETSC_HAVE_VECCUDA)
5598: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5599: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5600: }
5601: #endif
5602: return(0);
5603: }
5607: /*@C
5608: MatZeroRowsColumnsIS - Zeros all entries (except possibly the main diagonal)
5609: of a set of rows and columns of a matrix.
5611: Collective on Mat
5613: Input Parameters:
5614: + mat - the matrix
5615: . is - the rows to zero
5616: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5617: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5618: - b - optional vector of right hand side, that will be adjusted by provided solution
5620: Notes:
5621: This does not change the nonzero structure of the matrix, it merely zeros those entries in the matrix.
5623: The user can set a value in the diagonal entry (or for the AIJ and
5624: row formats can optionally remove the main diagonal entry from the
5625: nonzero structure as well, by passing 0.0 as the final argument).
5627: For the parallel case, all processes that share the matrix (i.e.,
5628: those in the communicator used for matrix creation) MUST call this
5629: routine, regardless of whether any rows being zeroed are owned by
5630: them.
5632: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5633: list only rows local to itself).
5635: The option MAT_NO_OFF_PROC_ZERO_ROWS does not apply to this routine.
5637: Level: intermediate
5639: Concepts: matrices^zeroing rows
5641: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption(), MatZeroRowsColumns()
5642: @*/
5643: PetscErrorCode MatZeroRowsColumnsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5644: {
5646: PetscInt numRows;
5647: const PetscInt *rows;
5654: ISGetLocalSize(is,&numRows);
5655: ISGetIndices(is,&rows);
5656: MatZeroRowsColumns(mat,numRows,rows,diag,x,b);
5657: ISRestoreIndices(is,&rows);
5658: return(0);
5659: }
5663: /*@C
5664: MatZeroRows - Zeros all entries (except possibly the main diagonal)
5665: of a set of rows of a matrix.
5667: Collective on Mat
5669: Input Parameters:
5670: + mat - the matrix
5671: . numRows - the number of rows to remove
5672: . rows - the global row indices
5673: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5674: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5675: - b - optional vector of right hand side, that will be adjusted by provided solution
5677: Notes:
5678: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5679: but does not release memory. For the dense and block diagonal
5680: formats this does not alter the nonzero structure.
5682: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5683: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5684: merely zeroed.
5686: The user can set a value in the diagonal entry (or for the AIJ and
5687: row formats can optionally remove the main diagonal entry from the
5688: nonzero structure as well, by passing 0.0 as the final argument).
5690: For the parallel case, all processes that share the matrix (i.e.,
5691: those in the communicator used for matrix creation) MUST call this
5692: routine, regardless of whether any rows being zeroed are owned by
5693: them.
5695: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5696: list only rows local to itself).
5698: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5699: owns that are to be zeroed. This saves a global synchronization in the implementation.
5701: Level: intermediate
5703: Concepts: matrices^zeroing rows
5705: .seealso: MatZeroRowsIS(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5706: @*/
5707: PetscErrorCode MatZeroRows(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
5708: {
5715: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
5716: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
5717: if (!mat->ops->zerorows) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
5718: MatCheckPreallocated(mat,1);
5720: (*mat->ops->zerorows)(mat,numRows,rows,diag,x,b);
5721: MatViewFromOptions(mat,NULL,"-mat_view");
5722: PetscObjectStateIncrease((PetscObject)mat);
5723: #if defined(PETSC_HAVE_CUSP)
5724: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
5725: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
5726: }
5727: #elif defined(PETSC_HAVE_VIENNACL)
5728: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
5729: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
5730: }
5731: #elif defined(PETSC_HAVE_VECCUDA)
5732: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
5733: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
5734: }
5735: #endif
5736: return(0);
5737: }
5741: /*@C
5742: MatZeroRowsIS - Zeros all entries (except possibly the main diagonal)
5743: of a set of rows of a matrix.
5745: Collective on Mat
5747: Input Parameters:
5748: + mat - the matrix
5749: . is - index set of rows to remove
5750: . diag - value put in all diagonals of eliminated rows
5751: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5752: - b - optional vector of right hand side, that will be adjusted by provided solution
5754: Notes:
5755: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5756: but does not release memory. For the dense and block diagonal
5757: formats this does not alter the nonzero structure.
5759: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5760: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5761: merely zeroed.
5763: The user can set a value in the diagonal entry (or for the AIJ and
5764: row formats can optionally remove the main diagonal entry from the
5765: nonzero structure as well, by passing 0.0 as the final argument).
5767: For the parallel case, all processes that share the matrix (i.e.,
5768: those in the communicator used for matrix creation) MUST call this
5769: routine, regardless of whether any rows being zeroed are owned by
5770: them.
5772: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5773: list only rows local to itself).
5775: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
5776: owns that are to be zeroed. This saves a global synchronization in the implementation.
5778: Level: intermediate
5780: Concepts: matrices^zeroing rows
5782: .seealso: MatZeroRows(), MatZeroRowsStencil(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5783: @*/
5784: PetscErrorCode MatZeroRowsIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
5785: {
5786: PetscInt numRows;
5787: const PetscInt *rows;
5794: ISGetLocalSize(is,&numRows);
5795: ISGetIndices(is,&rows);
5796: MatZeroRows(mat,numRows,rows,diag,x,b);
5797: ISRestoreIndices(is,&rows);
5798: return(0);
5799: }
5803: /*@C
5804: MatZeroRowsStencil - Zeros all entries (except possibly the main diagonal)
5805: of a set of rows of a matrix. These rows must be local to the process.
5807: Collective on Mat
5809: Input Parameters:
5810: + mat - the matrix
5811: . numRows - the number of rows to remove
5812: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5813: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5814: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5815: - b - optional vector of right hand side, that will be adjusted by provided solution
5817: Notes:
5818: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5819: but does not release memory. For the dense and block diagonal
5820: formats this does not alter the nonzero structure.
5822: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5823: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5824: merely zeroed.
5826: The user can set a value in the diagonal entry (or for the AIJ and
5827: row formats can optionally remove the main diagonal entry from the
5828: nonzero structure as well, by passing 0.0 as the final argument).
5830: For the parallel case, all processes that share the matrix (i.e.,
5831: those in the communicator used for matrix creation) MUST call this
5832: routine, regardless of whether any rows being zeroed are owned by
5833: them.
5835: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5836: list only rows local to itself).
5838: The grid coordinates are across the entire grid, not just the local portion
5840: In Fortran idxm and idxn should be declared as
5841: $ MatStencil idxm(4,m)
5842: and the values inserted using
5843: $ idxm(MatStencil_i,1) = i
5844: $ idxm(MatStencil_j,1) = j
5845: $ idxm(MatStencil_k,1) = k
5846: $ idxm(MatStencil_c,1) = c
5847: etc
5849: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5850: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5851: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5852: DM_BOUNDARY_PERIODIC boundary type.
5854: 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
5855: a single value per point) you can skip filling those indices.
5857: Level: intermediate
5859: Concepts: matrices^zeroing rows
5861: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5862: @*/
5863: PetscErrorCode MatZeroRowsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5864: {
5865: PetscInt dim = mat->stencil.dim;
5866: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5867: PetscInt *dims = mat->stencil.dims+1;
5868: PetscInt *starts = mat->stencil.starts;
5869: PetscInt *dxm = (PetscInt*) rows;
5870: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5878: PetscMalloc1(numRows, &jdxm);
5879: for (i = 0; i < numRows; ++i) {
5880: /* Skip unused dimensions (they are ordered k, j, i, c) */
5881: for (j = 0; j < 3-sdim; ++j) dxm++;
5882: /* Local index in X dir */
5883: tmp = *dxm++ - starts[0];
5884: /* Loop over remaining dimensions */
5885: for (j = 0; j < dim-1; ++j) {
5886: /* If nonlocal, set index to be negative */
5887: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5888: /* Update local index */
5889: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5890: }
5891: /* Skip component slot if necessary */
5892: if (mat->stencil.noc) dxm++;
5893: /* Local row number */
5894: if (tmp >= 0) {
5895: jdxm[numNewRows++] = tmp;
5896: }
5897: }
5898: MatZeroRowsLocal(mat,numNewRows,jdxm,diag,x,b);
5899: PetscFree(jdxm);
5900: return(0);
5901: }
5905: /*@C
5906: MatZeroRowsColumnsStencil - Zeros all row and column entries (except possibly the main diagonal)
5907: of a set of rows and columns of a matrix.
5909: Collective on Mat
5911: Input Parameters:
5912: + mat - the matrix
5913: . numRows - the number of rows/columns to remove
5914: . rows - the grid coordinates (and component number when dof > 1) for matrix rows
5915: . diag - value put in all diagonals of eliminated rows (0.0 will even eliminate diagonal entry)
5916: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
5917: - b - optional vector of right hand side, that will be adjusted by provided solution
5919: Notes:
5920: For the AIJ and BAIJ matrix formats this removes the old nonzero structure,
5921: but does not release memory. For the dense and block diagonal
5922: formats this does not alter the nonzero structure.
5924: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
5925: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
5926: merely zeroed.
5928: The user can set a value in the diagonal entry (or for the AIJ and
5929: row formats can optionally remove the main diagonal entry from the
5930: nonzero structure as well, by passing 0.0 as the final argument).
5932: For the parallel case, all processes that share the matrix (i.e.,
5933: those in the communicator used for matrix creation) MUST call this
5934: routine, regardless of whether any rows being zeroed are owned by
5935: them.
5937: Each processor can indicate any rows in the entire matrix to be zeroed (i.e. each process does NOT have to
5938: list only rows local to itself, but the row/column numbers are given in local numbering).
5940: The grid coordinates are across the entire grid, not just the local portion
5942: In Fortran idxm and idxn should be declared as
5943: $ MatStencil idxm(4,m)
5944: and the values inserted using
5945: $ idxm(MatStencil_i,1) = i
5946: $ idxm(MatStencil_j,1) = j
5947: $ idxm(MatStencil_k,1) = k
5948: $ idxm(MatStencil_c,1) = c
5949: etc
5951: For periodic boundary conditions use negative indices for values to the left (below 0; that are to be
5952: obtained by wrapping values from right edge). For values to the right of the last entry using that index plus one
5953: etc to obtain values that obtained by wrapping the values from the left edge. This does not work for anything but the
5954: DM_BOUNDARY_PERIODIC boundary type.
5956: 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
5957: a single value per point) you can skip filling those indices.
5959: Level: intermediate
5961: Concepts: matrices^zeroing rows
5963: .seealso: MatZeroRows(), MatZeroRowsIS(), MatZeroEntries(), MatZeroRowsLocal(), MatSetOption()
5964: @*/
5965: PetscErrorCode MatZeroRowsColumnsStencil(Mat mat,PetscInt numRows,const MatStencil rows[],PetscScalar diag,Vec x,Vec b)
5966: {
5967: PetscInt dim = mat->stencil.dim;
5968: PetscInt sdim = dim - (1 - (PetscInt) mat->stencil.noc);
5969: PetscInt *dims = mat->stencil.dims+1;
5970: PetscInt *starts = mat->stencil.starts;
5971: PetscInt *dxm = (PetscInt*) rows;
5972: PetscInt *jdxm, i, j, tmp, numNewRows = 0;
5980: PetscMalloc1(numRows, &jdxm);
5981: for (i = 0; i < numRows; ++i) {
5982: /* Skip unused dimensions (they are ordered k, j, i, c) */
5983: for (j = 0; j < 3-sdim; ++j) dxm++;
5984: /* Local index in X dir */
5985: tmp = *dxm++ - starts[0];
5986: /* Loop over remaining dimensions */
5987: for (j = 0; j < dim-1; ++j) {
5988: /* If nonlocal, set index to be negative */
5989: if ((*dxm++ - starts[j+1]) < 0 || tmp < 0) tmp = PETSC_MIN_INT;
5990: /* Update local index */
5991: else tmp = tmp*dims[j] + *(dxm-1) - starts[j+1];
5992: }
5993: /* Skip component slot if necessary */
5994: if (mat->stencil.noc) dxm++;
5995: /* Local row number */
5996: if (tmp >= 0) {
5997: jdxm[numNewRows++] = tmp;
5998: }
5999: }
6000: MatZeroRowsColumnsLocal(mat,numNewRows,jdxm,diag,x,b);
6001: PetscFree(jdxm);
6002: return(0);
6003: }
6007: /*@C
6008: MatZeroRowsLocal - Zeros all entries (except possibly the main diagonal)
6009: of a set of rows of a matrix; using local numbering of rows.
6011: Collective on Mat
6013: Input Parameters:
6014: + mat - the matrix
6015: . numRows - the number of rows to remove
6016: . rows - the global row indices
6017: . diag - value put in all diagonals of eliminated rows
6018: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6019: - b - optional vector of right hand side, that will be adjusted by provided solution
6021: Notes:
6022: Before calling MatZeroRowsLocal(), the user must first set the
6023: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6025: For the AIJ matrix formats this removes the old nonzero structure,
6026: but does not release memory. For the dense and block diagonal
6027: formats this does not alter the nonzero structure.
6029: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6030: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6031: merely zeroed.
6033: The user can set a value in the diagonal entry (or for the AIJ and
6034: row formats can optionally remove the main diagonal entry from the
6035: nonzero structure as well, by passing 0.0 as the final argument).
6037: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6038: owns that are to be zeroed. This saves a global synchronization in the implementation.
6040: Level: intermediate
6042: Concepts: matrices^zeroing
6044: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6045: @*/
6046: PetscErrorCode MatZeroRowsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6047: {
6054: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6055: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6056: MatCheckPreallocated(mat,1);
6058: if (mat->ops->zerorowslocal) {
6059: (*mat->ops->zerorowslocal)(mat,numRows,rows,diag,x,b);
6060: } else {
6061: IS is, newis;
6062: const PetscInt *newRows;
6064: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6065: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6066: ISLocalToGlobalMappingApplyIS(mat->rmap->mapping,is,&newis);
6067: ISGetIndices(newis,&newRows);
6068: (*mat->ops->zerorows)(mat,numRows,newRows,diag,x,b);
6069: ISRestoreIndices(newis,&newRows);
6070: ISDestroy(&newis);
6071: ISDestroy(&is);
6072: }
6073: PetscObjectStateIncrease((PetscObject)mat);
6074: #if defined(PETSC_HAVE_CUSP)
6075: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6076: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6077: }
6078: #elif defined(PETSC_HAVE_VIENNACL)
6079: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6080: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6081: }
6082: #elif defined(PETSC_HAVE_VECCUDA)
6083: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6084: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6085: }
6086: #endif
6087: return(0);
6088: }
6092: /*@C
6093: MatZeroRowsLocalIS - Zeros all entries (except possibly the main diagonal)
6094: of a set of rows of a matrix; using local numbering of rows.
6096: Collective on Mat
6098: Input Parameters:
6099: + mat - the matrix
6100: . is - index set of rows to remove
6101: . diag - value put in all diagonals of eliminated rows
6102: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6103: - b - optional vector of right hand side, that will be adjusted by provided solution
6105: Notes:
6106: Before calling MatZeroRowsLocalIS(), the user must first set the
6107: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6109: For the AIJ matrix formats this removes the old nonzero structure,
6110: but does not release memory. For the dense and block diagonal
6111: formats this does not alter the nonzero structure.
6113: If the option MatSetOption(mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE) the nonzero structure
6114: of the matrix is not changed (even for AIJ and BAIJ matrices) the values are
6115: merely zeroed.
6117: The user can set a value in the diagonal entry (or for the AIJ and
6118: row formats can optionally remove the main diagonal entry from the
6119: nonzero structure as well, by passing 0.0 as the final argument).
6121: You can call MatSetOption(mat,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE) if each process indicates only rows it
6122: owns that are to be zeroed. This saves a global synchronization in the implementation.
6124: Level: intermediate
6126: Concepts: matrices^zeroing
6128: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6129: @*/
6130: PetscErrorCode MatZeroRowsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6131: {
6133: PetscInt numRows;
6134: const PetscInt *rows;
6140: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6141: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6142: MatCheckPreallocated(mat,1);
6144: ISGetLocalSize(is,&numRows);
6145: ISGetIndices(is,&rows);
6146: MatZeroRowsLocal(mat,numRows,rows,diag,x,b);
6147: ISRestoreIndices(is,&rows);
6148: return(0);
6149: }
6153: /*@C
6154: MatZeroRowsColumnsLocal - Zeros all entries (except possibly the main diagonal)
6155: of a set of rows and columns of a matrix; using local numbering of rows.
6157: Collective on Mat
6159: Input Parameters:
6160: + mat - the matrix
6161: . numRows - the number of rows to remove
6162: . rows - the global row indices
6163: . diag - value put in all diagonals of eliminated rows
6164: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6165: - b - optional vector of right hand side, that will be adjusted by provided solution
6167: Notes:
6168: Before calling MatZeroRowsColumnsLocal(), the user must first set the
6169: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6171: The user can set a value in the diagonal entry (or for the AIJ and
6172: row formats can optionally remove the main diagonal entry from the
6173: nonzero structure as well, by passing 0.0 as the final argument).
6175: Level: intermediate
6177: Concepts: matrices^zeroing
6179: .seealso: MatZeroRows(), MatZeroRowsLocalIS(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6180: @*/
6181: PetscErrorCode MatZeroRowsColumnsLocal(Mat mat,PetscInt numRows,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
6182: {
6184: IS is, newis;
6185: const PetscInt *newRows;
6191: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6192: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6193: MatCheckPreallocated(mat,1);
6195: if (!mat->cmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Need to provide local to global mapping to matrix first");
6196: ISCreateGeneral(PETSC_COMM_SELF,numRows,rows,PETSC_COPY_VALUES,&is);
6197: ISLocalToGlobalMappingApplyIS(mat->cmap->mapping,is,&newis);
6198: ISGetIndices(newis,&newRows);
6199: (*mat->ops->zerorowscolumns)(mat,numRows,newRows,diag,x,b);
6200: ISRestoreIndices(newis,&newRows);
6201: ISDestroy(&newis);
6202: ISDestroy(&is);
6203: PetscObjectStateIncrease((PetscObject)mat);
6204: #if defined(PETSC_HAVE_CUSP)
6205: if (mat->valid_GPU_matrix != PETSC_CUSP_UNALLOCATED) {
6206: mat->valid_GPU_matrix = PETSC_CUSP_CPU;
6207: }
6208: #elif defined(PETSC_HAVE_VIENNACL)
6209: if (mat->valid_GPU_matrix != PETSC_VIENNACL_UNALLOCATED) {
6210: mat->valid_GPU_matrix = PETSC_VIENNACL_CPU;
6211: }
6212: #elif defined(PETSC_HAVE_VECCUDA)
6213: if (mat->valid_GPU_matrix != PETSC_CUDA_UNALLOCATED) {
6214: mat->valid_GPU_matrix = PETSC_CUDA_CPU;
6215: }
6216: #endif
6217: return(0);
6218: }
6222: /*@C
6223: MatZeroRowsColumnsLocalIS - Zeros all entries (except possibly the main diagonal)
6224: of a set of rows and columns of a matrix; using local numbering of rows.
6226: Collective on Mat
6228: Input Parameters:
6229: + mat - the matrix
6230: . is - index set of rows to remove
6231: . diag - value put in all diagonals of eliminated rows
6232: . x - optional vector of solutions for zeroed rows (other entries in vector are not used)
6233: - b - optional vector of right hand side, that will be adjusted by provided solution
6235: Notes:
6236: Before calling MatZeroRowsColumnsLocalIS(), the user must first set the
6237: local-to-global mapping by calling MatSetLocalToGlobalMapping().
6239: The user can set a value in the diagonal entry (or for the AIJ and
6240: row formats can optionally remove the main diagonal entry from the
6241: nonzero structure as well, by passing 0.0 as the final argument).
6243: Level: intermediate
6245: Concepts: matrices^zeroing
6247: .seealso: MatZeroRows(), MatZeroRowsLocal(), MatZeroEntries(), MatZeroRows(), MatSetLocalToGlobalMapping
6248: @*/
6249: PetscErrorCode MatZeroRowsColumnsLocalIS(Mat mat,IS is,PetscScalar diag,Vec x,Vec b)
6250: {
6252: PetscInt numRows;
6253: const PetscInt *rows;
6259: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6260: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6261: MatCheckPreallocated(mat,1);
6263: ISGetLocalSize(is,&numRows);
6264: ISGetIndices(is,&rows);
6265: MatZeroRowsColumnsLocal(mat,numRows,rows,diag,x,b);
6266: ISRestoreIndices(is,&rows);
6267: return(0);
6268: }
6272: /*@
6273: MatGetSize - Returns the numbers of rows and columns in a matrix.
6275: Not Collective
6277: Input Parameter:
6278: . mat - the matrix
6280: Output Parameters:
6281: + m - the number of global rows
6282: - n - the number of global columns
6284: Note: both output parameters can be NULL on input.
6286: Level: beginner
6288: Concepts: matrices^size
6290: .seealso: MatGetLocalSize()
6291: @*/
6292: PetscErrorCode MatGetSize(Mat mat,PetscInt *m,PetscInt *n)
6293: {
6296: if (m) *m = mat->rmap->N;
6297: if (n) *n = mat->cmap->N;
6298: return(0);
6299: }
6303: /*@
6304: MatGetLocalSize - Returns the number of rows and columns in a matrix
6305: stored locally. This information may be implementation dependent, so
6306: use with care.
6308: Not Collective
6310: Input Parameters:
6311: . mat - the matrix
6313: Output Parameters:
6314: + m - the number of local rows
6315: - n - the number of local columns
6317: Note: both output parameters can be NULL on input.
6319: Level: beginner
6321: Concepts: matrices^local size
6323: .seealso: MatGetSize()
6324: @*/
6325: PetscErrorCode MatGetLocalSize(Mat mat,PetscInt *m,PetscInt *n)
6326: {
6331: if (m) *m = mat->rmap->n;
6332: if (n) *n = mat->cmap->n;
6333: return(0);
6334: }
6338: /*@
6339: MatGetOwnershipRangeColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6340: this processor. (The columns of the "diagonal block")
6342: Not Collective, unless matrix has not been allocated, then collective on Mat
6344: Input Parameters:
6345: . mat - the matrix
6347: Output Parameters:
6348: + m - the global index of the first local column
6349: - n - one more than the global index of the last local column
6351: Notes: both output parameters can be NULL on input.
6353: Level: developer
6355: Concepts: matrices^column ownership
6357: .seealso: MatGetOwnershipRange(), MatGetOwnershipRanges(), MatGetOwnershipRangesColumn()
6359: @*/
6360: PetscErrorCode MatGetOwnershipRangeColumn(Mat mat,PetscInt *m,PetscInt *n)
6361: {
6367: MatCheckPreallocated(mat,1);
6368: if (m) *m = mat->cmap->rstart;
6369: if (n) *n = mat->cmap->rend;
6370: return(0);
6371: }
6375: /*@
6376: MatGetOwnershipRange - Returns the range of matrix rows owned by
6377: this processor, assuming that the matrix is laid out with the first
6378: n1 rows on the first processor, the next n2 rows on the second, etc.
6379: For certain parallel layouts this range may not be well defined.
6381: Not Collective
6383: Input Parameters:
6384: . mat - the matrix
6386: Output Parameters:
6387: + m - the global index of the first local row
6388: - n - one more than the global index of the last local row
6390: Note: Both output parameters can be NULL on input.
6391: $ This function requires that the matrix be preallocated. If you have not preallocated, consider using
6392: $ PetscSplitOwnership(MPI_Comm comm, PetscInt *n, PetscInt *N)
6393: $ and then MPI_Scan() to calculate prefix sums of the local sizes.
6395: Level: beginner
6397: Concepts: matrices^row ownership
6399: .seealso: MatGetOwnershipRanges(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn(), PetscSplitOwnership(), PetscSplitOwnershipBlock()
6401: @*/
6402: PetscErrorCode MatGetOwnershipRange(Mat mat,PetscInt *m,PetscInt *n)
6403: {
6409: MatCheckPreallocated(mat,1);
6410: if (m) *m = mat->rmap->rstart;
6411: if (n) *n = mat->rmap->rend;
6412: return(0);
6413: }
6417: /*@C
6418: MatGetOwnershipRanges - Returns the range of matrix rows owned by
6419: each process
6421: Not Collective, unless matrix has not been allocated, then collective on Mat
6423: Input Parameters:
6424: . mat - the matrix
6426: Output Parameters:
6427: . ranges - start of each processors portion plus one more than the total length at the end
6429: Level: beginner
6431: Concepts: matrices^row ownership
6433: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRangesColumn()
6435: @*/
6436: PetscErrorCode MatGetOwnershipRanges(Mat mat,const PetscInt **ranges)
6437: {
6443: MatCheckPreallocated(mat,1);
6444: PetscLayoutGetRanges(mat->rmap,ranges);
6445: return(0);
6446: }
6450: /*@C
6451: MatGetOwnershipRangesColumn - Returns the range of matrix columns associated with rows of a vector one multiplies by that owned by
6452: this processor. (The columns of the "diagonal blocks" for each process)
6454: Not Collective, unless matrix has not been allocated, then collective on Mat
6456: Input Parameters:
6457: . mat - the matrix
6459: Output Parameters:
6460: . ranges - start of each processors portion plus one more then the total length at the end
6462: Level: beginner
6464: Concepts: matrices^column ownership
6466: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatGetOwnershipRanges()
6468: @*/
6469: PetscErrorCode MatGetOwnershipRangesColumn(Mat mat,const PetscInt **ranges)
6470: {
6476: MatCheckPreallocated(mat,1);
6477: PetscLayoutGetRanges(mat->cmap,ranges);
6478: return(0);
6479: }
6483: /*@C
6484: MatGetOwnershipIS - Get row and column ownership as index sets
6486: Not Collective
6488: Input Arguments:
6489: . A - matrix of type Elemental
6491: Output Arguments:
6492: + rows - rows in which this process owns elements
6493: . cols - columns in which this process owns elements
6495: Level: intermediate
6497: .seealso: MatGetOwnershipRange(), MatGetOwnershipRangeColumn(), MatSetValues(), MATELEMENTAL, MatSetValues()
6498: @*/
6499: PetscErrorCode MatGetOwnershipIS(Mat A,IS *rows,IS *cols)
6500: {
6501: PetscErrorCode ierr,(*f)(Mat,IS*,IS*);
6504: MatCheckPreallocated(A,1);
6505: PetscObjectQueryFunction((PetscObject)A,"MatGetOwnershipIS_C",&f);
6506: if (f) {
6507: (*f)(A,rows,cols);
6508: } else { /* Create a standard row-based partition, each process is responsible for ALL columns in their row block */
6509: if (rows) {ISCreateStride(PETSC_COMM_SELF,A->rmap->n,A->rmap->rstart,1,rows);}
6510: if (cols) {ISCreateStride(PETSC_COMM_SELF,A->cmap->N,0,1,cols);}
6511: }
6512: return(0);
6513: }
6517: /*@C
6518: MatILUFactorSymbolic - Performs symbolic ILU factorization of a matrix.
6519: Uses levels of fill only, not drop tolerance. Use MatLUFactorNumeric()
6520: to complete the factorization.
6522: Collective on Mat
6524: Input Parameters:
6525: + mat - the matrix
6526: . row - row permutation
6527: . column - column permutation
6528: - info - structure containing
6529: $ levels - number of levels of fill.
6530: $ expected fill - as ratio of original fill.
6531: $ 1 or 0 - indicating force fill on diagonal (improves robustness for matrices
6532: missing diagonal entries)
6534: Output Parameters:
6535: . fact - new matrix that has been symbolically factored
6537: Notes: See Users-Manual: ch_mat for additional information about choosing the fill factor for better efficiency.
6539: Most users should employ the simplified KSP interface for linear solvers
6540: instead of working directly with matrix algebra routines such as this.
6541: See, e.g., KSPCreate().
6543: Level: developer
6545: Concepts: matrices^symbolic LU factorization
6546: Concepts: matrices^factorization
6547: Concepts: LU^symbolic factorization
6549: .seealso: MatLUFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
6550: MatGetOrdering(), MatFactorInfo
6552: Developer Note: fortran interface is not autogenerated as the f90
6553: interface defintion cannot be generated correctly [due to MatFactorInfo]
6555: @*/
6556: PetscErrorCode MatILUFactorSymbolic(Mat fact,Mat mat,IS row,IS col,const MatFactorInfo *info)
6557: {
6567: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels of fill negative %D",(PetscInt)info->levels);
6568: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6569: if (!(fact)->ops->ilufactorsymbolic) {
6570: const MatSolverPackage spackage;
6571: MatFactorGetSolverPackage(fact,&spackage);
6572: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ILU using solver package %s",((PetscObject)mat)->type_name,spackage);
6573: }
6574: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6575: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6576: MatCheckPreallocated(mat,2);
6578: PetscLogEventBegin(MAT_ILUFactorSymbolic,mat,row,col,0);
6579: (fact->ops->ilufactorsymbolic)(fact,mat,row,col,info);
6580: PetscLogEventEnd(MAT_ILUFactorSymbolic,mat,row,col,0);
6581: return(0);
6582: }
6586: /*@C
6587: MatICCFactorSymbolic - Performs symbolic incomplete
6588: Cholesky factorization for a symmetric matrix. Use
6589: MatCholeskyFactorNumeric() to complete the factorization.
6591: Collective on Mat
6593: Input Parameters:
6594: + mat - the matrix
6595: . perm - row and column permutation
6596: - info - structure containing
6597: $ levels - number of levels of fill.
6598: $ expected fill - as ratio of original fill.
6600: Output Parameter:
6601: . fact - the factored matrix
6603: Notes:
6604: Most users should employ the KSP interface for linear solvers
6605: instead of working directly with matrix algebra routines such as this.
6606: See, e.g., KSPCreate().
6608: Level: developer
6610: Concepts: matrices^symbolic incomplete Cholesky factorization
6611: Concepts: matrices^factorization
6612: Concepts: Cholsky^symbolic factorization
6614: .seealso: MatCholeskyFactorNumeric(), MatCholeskyFactor(), MatFactorInfo
6616: Developer Note: fortran interface is not autogenerated as the f90
6617: interface defintion cannot be generated correctly [due to MatFactorInfo]
6619: @*/
6620: PetscErrorCode MatICCFactorSymbolic(Mat fact,Mat mat,IS perm,const MatFactorInfo *info)
6621: {
6630: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6631: if (info->levels < 0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Levels negative %D",(PetscInt) info->levels);
6632: if (info->fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Expected fill less than 1.0 %g",(double)info->fill);
6633: if (!(fact)->ops->iccfactorsymbolic) {
6634: const MatSolverPackage spackage;
6635: MatFactorGetSolverPackage(fact,&spackage);
6636: SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Matrix type %s symbolic ICC using solver package %s",((PetscObject)mat)->type_name,spackage);
6637: }
6638: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6639: MatCheckPreallocated(mat,2);
6641: PetscLogEventBegin(MAT_ICCFactorSymbolic,mat,perm,0,0);
6642: (fact->ops->iccfactorsymbolic)(fact,mat,perm,info);
6643: PetscLogEventEnd(MAT_ICCFactorSymbolic,mat,perm,0,0);
6644: return(0);
6645: }
6649: /*@C
6650: MatGetSubMatrices - Extracts several submatrices from a matrix. If submat
6651: points to an array of valid matrices, they may be reused to store the new
6652: submatrices.
6654: Collective on Mat
6656: Input Parameters:
6657: + mat - the matrix
6658: . n - the number of submatrixes to be extracted (on this processor, may be zero)
6659: . irow, icol - index sets of rows and columns to extract
6660: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
6662: Output Parameter:
6663: . submat - the array of submatrices
6665: Notes:
6666: MatGetSubMatrices() can extract ONLY sequential submatrices
6667: (from both sequential and parallel matrices). Use MatGetSubMatrix()
6668: to extract a parallel submatrix.
6670: Some matrix types place restrictions on the row and column
6671: indices, such as that they be sorted or that they be equal to each other.
6673: The index sets may not have duplicate entries.
6675: When extracting submatrices from a parallel matrix, each processor can
6676: form a different submatrix by setting the rows and columns of its
6677: individual index sets according to the local submatrix desired.
6679: When finished using the submatrices, the user should destroy
6680: them with MatDestroyMatrices().
6682: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
6683: original matrix has not changed from that last call to MatGetSubMatrices().
6685: This routine creates the matrices in submat; you should NOT create them before
6686: calling it. It also allocates the array of matrix pointers submat.
6688: For BAIJ matrices the index sets must respect the block structure, that is if they
6689: request one row/column in a block, they must request all rows/columns that are in
6690: that block. For example, if the block size is 2 you cannot request just row 0 and
6691: column 0.
6693: Fortran Note:
6694: The Fortran interface is slightly different from that given below; it
6695: requires one to pass in as submat a Mat (integer) array of size at least m.
6697: Level: advanced
6699: Concepts: matrices^accessing submatrices
6700: Concepts: submatrices
6702: .seealso: MatDestroyMatrices(), MatGetSubMatrix(), MatGetRow(), MatGetDiagonal(), MatReuse
6703: @*/
6704: PetscErrorCode MatGetSubMatrices(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6705: {
6707: PetscInt i;
6708: PetscBool eq;
6713: if (n) {
6718: }
6720: if (n && scall == MAT_REUSE_MATRIX) {
6723: }
6724: if (!mat->ops->getsubmatrices) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6725: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6726: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6727: MatCheckPreallocated(mat,1);
6729: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6730: (*mat->ops->getsubmatrices)(mat,n,irow,icol,scall,submat);
6731: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6732: for (i=0; i<n; i++) {
6733: (*submat)[i]->factortype = MAT_FACTOR_NONE; /* in case in place factorization was previously done on submatrix */
6734: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6735: ISEqual(irow[i],icol[i],&eq);
6736: if (eq) {
6737: if (mat->symmetric) {
6738: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6739: } else if (mat->hermitian) {
6740: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6741: } else if (mat->structurally_symmetric) {
6742: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6743: }
6744: }
6745: }
6746: }
6747: return(0);
6748: }
6752: PetscErrorCode MatGetSubMatricesMPI(Mat mat,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *submat[])
6753: {
6755: PetscInt i;
6756: PetscBool eq;
6761: if (n) {
6766: }
6768: if (n && scall == MAT_REUSE_MATRIX) {
6771: }
6772: if (!mat->ops->getsubmatricesmpi) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6773: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6774: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6775: MatCheckPreallocated(mat,1);
6777: PetscLogEventBegin(MAT_GetSubMatrices,mat,0,0,0);
6778: (*mat->ops->getsubmatricesmpi)(mat,n,irow,icol,scall,submat);
6779: PetscLogEventEnd(MAT_GetSubMatrices,mat,0,0,0);
6780: for (i=0; i<n; i++) {
6781: if (mat->symmetric || mat->structurally_symmetric || mat->hermitian) {
6782: ISEqual(irow[i],icol[i],&eq);
6783: if (eq) {
6784: if (mat->symmetric) {
6785: MatSetOption((*submat)[i],MAT_SYMMETRIC,PETSC_TRUE);
6786: } else if (mat->hermitian) {
6787: MatSetOption((*submat)[i],MAT_HERMITIAN,PETSC_TRUE);
6788: } else if (mat->structurally_symmetric) {
6789: MatSetOption((*submat)[i],MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);
6790: }
6791: }
6792: }
6793: }
6794: return(0);
6795: }
6799: /*@C
6800: MatDestroyMatrices - Destroys a set of matrices obtained with MatGetSubMatrices().
6802: Collective on Mat
6804: Input Parameters:
6805: + n - the number of local matrices
6806: - mat - the matrices (note that this is a pointer to the array of matrices, just to match the calling
6807: sequence of MatGetSubMatrices())
6809: Level: advanced
6811: Notes: Frees not only the matrices, but also the array that contains the matrices
6812: In Fortran will not free the array.
6814: .seealso: MatGetSubMatrices()
6815: @*/
6816: PetscErrorCode MatDestroyMatrices(PetscInt n,Mat *mat[])
6817: {
6819: PetscInt i;
6822: if (!*mat) return(0);
6823: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Trying to destroy negative number of matrices %D",n);
6825: for (i=0; i<n; i++) {
6826: MatDestroy(&(*mat)[i]);
6827: }
6828: /* memory is allocated even if n = 0 */
6829: PetscFree(*mat);
6830: *mat = NULL;
6831: return(0);
6832: }
6836: /*@C
6837: MatGetSeqNonzeroStructure - Extracts the sequential nonzero structure from a matrix.
6839: Collective on Mat
6841: Input Parameters:
6842: . mat - the matrix
6844: Output Parameter:
6845: . matstruct - the sequential matrix with the nonzero structure of mat
6847: Level: intermediate
6849: .seealso: MatDestroySeqNonzeroStructure(), MatGetSubMatrices(), MatDestroyMatrices()
6850: @*/
6851: PetscErrorCode MatGetSeqNonzeroStructure(Mat mat,Mat *matstruct)
6852: {
6860: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6861: MatCheckPreallocated(mat,1);
6863: if (!mat->ops->getseqnonzerostructure) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)mat)->type_name);
6864: PetscLogEventBegin(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6865: (*mat->ops->getseqnonzerostructure)(mat,matstruct);
6866: PetscLogEventEnd(MAT_GetSeqNonzeroStructure,mat,0,0,0);
6867: return(0);
6868: }
6872: /*@C
6873: MatDestroySeqNonzeroStructure - Destroys matrix obtained with MatGetSeqNonzeroStructure().
6875: Collective on Mat
6877: Input Parameters:
6878: . mat - the matrix (note that this is a pointer to the array of matrices, just to match the calling
6879: sequence of MatGetSequentialNonzeroStructure())
6881: Level: advanced
6883: Notes: Frees not only the matrices, but also the array that contains the matrices
6885: .seealso: MatGetSeqNonzeroStructure()
6886: @*/
6887: PetscErrorCode MatDestroySeqNonzeroStructure(Mat *mat)
6888: {
6893: MatDestroy(mat);
6894: return(0);
6895: }
6899: /*@
6900: MatIncreaseOverlap - Given a set of submatrices indicated by index sets,
6901: replaces the index sets by larger ones that represent submatrices with
6902: additional overlap.
6904: Collective on Mat
6906: Input Parameters:
6907: + mat - the matrix
6908: . n - the number of index sets
6909: . is - the array of index sets (these index sets will changed during the call)
6910: - ov - the additional overlap requested
6912: Options Database:
6913: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6915: Level: developer
6917: Concepts: overlap
6918: Concepts: ASM^computing overlap
6920: .seealso: MatGetSubMatrices()
6921: @*/
6922: PetscErrorCode MatIncreaseOverlap(Mat mat,PetscInt n,IS is[],PetscInt ov)
6923: {
6929: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6930: if (n) {
6933: }
6934: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6935: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6936: MatCheckPreallocated(mat,1);
6938: if (!ov) return(0);
6939: if (!mat->ops->increaseoverlap) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
6940: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6941: (*mat->ops->increaseoverlap)(mat,n,is,ov);
6942: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6943: return(0);
6944: }
6947: PetscErrorCode MatIncreaseOverlapSplit_Single(Mat,IS*,PetscInt);
6951: /*@
6952: MatIncreaseOverlapSplit - Given a set of submatrices indicated by index sets across
6953: a sub communicator, replaces the index sets by larger ones that represent submatrices with
6954: additional overlap.
6956: Collective on Mat
6958: Input Parameters:
6959: + mat - the matrix
6960: . n - the number of index sets
6961: . is - the array of index sets (these index sets will changed during the call)
6962: - ov - the additional overlap requested
6964: Options Database:
6965: . -mat_increase_overlap_scalable - use a scalable algorithm to compute the overlap (supported by MPIAIJ matrix)
6967: Level: developer
6969: Concepts: overlap
6970: Concepts: ASM^computing overlap
6972: .seealso: MatGetSubMatrices()
6973: @*/
6974: PetscErrorCode MatIncreaseOverlapSplit(Mat mat,PetscInt n,IS is[],PetscInt ov)
6975: {
6976: PetscInt i;
6982: if (n < 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Must have one or more domains, you have %D",n);
6983: if (n) {
6986: }
6987: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
6988: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
6989: MatCheckPreallocated(mat,1);
6990: if (!ov) return(0);
6991: PetscLogEventBegin(MAT_IncreaseOverlap,mat,0,0,0);
6992: for(i=0; i<n; i++){
6993: MatIncreaseOverlapSplit_Single(mat,&is[i],ov);
6994: }
6995: PetscLogEventEnd(MAT_IncreaseOverlap,mat,0,0,0);
6996: return(0);
6997: }
7004: /*@
7005: MatGetBlockSize - Returns the matrix block size.
7007: Not Collective
7009: Input Parameter:
7010: . mat - the matrix
7012: Output Parameter:
7013: . bs - block size
7015: Notes:
7016: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7018: If the block size has not been set yet this routine returns 1.
7020: Level: intermediate
7022: Concepts: matrices^block size
7024: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSizes()
7025: @*/
7026: PetscErrorCode MatGetBlockSize(Mat mat,PetscInt *bs)
7027: {
7031: *bs = PetscAbs(mat->rmap->bs);
7032: return(0);
7033: }
7037: /*@
7038: MatGetBlockSizes - Returns the matrix block row and column sizes.
7040: Not Collective
7042: Input Parameter:
7043: . mat - the matrix
7045: Output Parameter:
7046: . rbs - row block size
7047: . cbs - coumn block size
7049: Notes:
7050: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7051: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7053: If a block size has not been set yet this routine returns 1.
7055: Level: intermediate
7057: Concepts: matrices^block size
7059: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatSetBlockSizes()
7060: @*/
7061: PetscErrorCode MatGetBlockSizes(Mat mat,PetscInt *rbs, PetscInt *cbs)
7062: {
7067: if (rbs) *rbs = PetscAbs(mat->rmap->bs);
7068: if (cbs) *cbs = PetscAbs(mat->cmap->bs);
7069: return(0);
7070: }
7074: /*@
7075: MatSetBlockSize - Sets the matrix block size.
7077: Logically Collective on Mat
7079: Input Parameters:
7080: + mat - the matrix
7081: - bs - block size
7083: Notes:
7084: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7086: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7088: Level: intermediate
7090: Concepts: matrices^block size
7092: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes(), MatGetBlockSizes()
7093: @*/
7094: PetscErrorCode MatSetBlockSize(Mat mat,PetscInt bs)
7095: {
7101: PetscLayoutSetBlockSize(mat->rmap,bs);
7102: PetscLayoutSetBlockSize(mat->cmap,bs);
7103: return(0);
7104: }
7108: /*@
7109: MatSetBlockSizes - Sets the matrix block row and column sizes.
7111: Logically Collective on Mat
7113: Input Parameters:
7114: + mat - the matrix
7115: - rbs - row block size
7116: - cbs - column block size
7118: Notes:
7119: Block row formats are MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ. These formats ALWAYS have square block storage in the matrix.
7120: If you pass a different block size for the columns than the rows, the row block size determines the square block storage.
7122: This must be called before MatSetUp() or MatXXXSetPreallocation() (or will default to 1) and the block size cannot be changed later
7124: The row and column block size determine the blocksize of the "row" and "column" vectors returned by MatCreateVecs().
7126: Level: intermediate
7128: Concepts: matrices^block size
7130: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSize(), MatGetBlockSizes()
7131: @*/
7132: PetscErrorCode MatSetBlockSizes(Mat mat,PetscInt rbs,PetscInt cbs)
7133: {
7140: PetscLayoutSetBlockSize(mat->rmap,rbs);
7141: PetscLayoutSetBlockSize(mat->cmap,cbs);
7142: return(0);
7143: }
7147: /*@
7148: MatSetBlockSizesFromMats - Sets the matrix block row and column sizes to match a pair of matrices
7150: Logically Collective on Mat
7152: Input Parameters:
7153: + mat - the matrix
7154: . fromRow - matrix from which to copy row block size
7155: - fromCol - matrix from which to copy column block size (can be same as fromRow)
7157: Level: developer
7159: Concepts: matrices^block size
7161: .seealso: MatCreateSeqBAIJ(), MatCreateBAIJ(), MatGetBlockSize(), MatSetBlockSizes()
7162: @*/
7163: PetscErrorCode MatSetBlockSizesFromMats(Mat mat,Mat fromRow,Mat fromCol)
7164: {
7171: if (fromRow->rmap->bs > 0) {PetscLayoutSetBlockSize(mat->rmap,fromRow->rmap->bs);}
7172: if (fromCol->cmap->bs > 0) {PetscLayoutSetBlockSize(mat->cmap,fromCol->cmap->bs);}
7173: return(0);
7174: }
7178: /*@
7179: MatResidual - Default routine to calculate the residual.
7181: Collective on Mat and Vec
7183: Input Parameters:
7184: + mat - the matrix
7185: . b - the right-hand-side
7186: - x - the approximate solution
7188: Output Parameter:
7189: . r - location to store the residual
7191: Level: developer
7193: .keywords: MG, default, multigrid, residual
7195: .seealso: PCMGSetResidual()
7196: @*/
7197: PetscErrorCode MatResidual(Mat mat,Vec b,Vec x,Vec r)
7198: {
7207: MatCheckPreallocated(mat,1);
7208: PetscLogEventBegin(MAT_Residual,mat,0,0,0);
7209: if (!mat->ops->residual) {
7210: MatMult(mat,x,r);
7211: VecAYPX(r,-1.0,b);
7212: } else {
7213: (*mat->ops->residual)(mat,b,x,r);
7214: }
7215: PetscLogEventEnd(MAT_Residual,mat,0,0,0);
7216: return(0);
7217: }
7221: /*@C
7222: MatGetRowIJ - Returns the compressed row storage i and j indices for sequential matrices.
7224: Collective on Mat
7226: Input Parameters:
7227: + mat - the matrix
7228: . shift - 0 or 1 indicating we want the indices starting at 0 or 1
7229: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be symmetrized
7230: - inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7231: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7232: always used.
7234: Output Parameters:
7235: + n - number of rows in the (possibly compressed) matrix
7236: . ia - the row pointers [of length n+1]
7237: . ja - the column indices
7238: - done - indicates if the routine actually worked and returned appropriate ia[] and ja[] arrays; callers
7239: are responsible for handling the case when done == PETSC_FALSE and ia and ja are not set
7241: Level: developer
7243: Notes: You CANNOT change any of the ia[] or ja[] values.
7245: Use MatRestoreRowIJ() when you are finished accessing the ia[] and ja[] values
7247: Fortran Node
7249: In Fortran use
7250: $ PetscInt ia(1), ja(1)
7251: $ PetscOffset iia, jja
7252: $ call MatGetRowIJ(mat,shift,symmetric,inodecompressed,n,ia,iia,ja,jja,done,ierr)
7253: $ Acess the ith and jth entries via ia(iia + i) and ja(jja + j)
7254: $
7255: $ or
7256: $
7257: $ PetscInt, pointer :: ia(:),ja(:)
7258: $ call MatGetRowIJF90(mat,shift,symmetric,inodecompressed,n,ia,ja,done,ierr)
7259: $ Acess the ith and jth entries via ia(i) and ja(j)
7263: .seealso: MatGetColumnIJ(), MatRestoreRowIJ(), MatSeqAIJGetArray()
7264: @*/
7265: PetscErrorCode MatGetRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7266: {
7276: MatCheckPreallocated(mat,1);
7277: if (!mat->ops->getrowij) *done = PETSC_FALSE;
7278: else {
7279: *done = PETSC_TRUE;
7280: PetscLogEventBegin(MAT_GetRowIJ,mat,0,0,0);
7281: (*mat->ops->getrowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7282: PetscLogEventEnd(MAT_GetRowIJ,mat,0,0,0);
7283: }
7284: return(0);
7285: }
7289: /*@C
7290: MatGetColumnIJ - Returns the compressed column storage i and j indices for sequential matrices.
7292: Collective on Mat
7294: Input Parameters:
7295: + mat - the matrix
7296: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7297: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7298: symmetrized
7299: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7300: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7301: always used.
7302: . n - number of columns in the (possibly compressed) matrix
7303: . ia - the column pointers
7304: - ja - the row indices
7306: Output Parameters:
7307: . done - PETSC_TRUE or PETSC_FALSE, indicating whether the values have been returned
7309: Note:
7310: This routine zeros out n, ia, and ja. This is to prevent accidental
7311: us of the array after it has been restored. If you pass NULL, it will
7312: not zero the pointers. Use of ia or ja after MatRestoreColumnIJ() is invalid.
7314: Level: developer
7316: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7317: @*/
7318: PetscErrorCode MatGetColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7319: {
7329: MatCheckPreallocated(mat,1);
7330: if (!mat->ops->getcolumnij) *done = PETSC_FALSE;
7331: else {
7332: *done = PETSC_TRUE;
7333: (*mat->ops->getcolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7334: }
7335: return(0);
7336: }
7340: /*@C
7341: MatRestoreRowIJ - Call after you are completed with the ia,ja indices obtained with
7342: MatGetRowIJ().
7344: Collective on Mat
7346: Input Parameters:
7347: + mat - the matrix
7348: . shift - 1 or zero indicating we want the indices starting at 0 or 1
7349: . symmetric - PETSC_TRUE or PETSC_FALSE indicating the matrix data structure should be
7350: symmetrized
7351: . inodecompressed - PETSC_TRUE or PETSC_FALSE indicating if the nonzero structure of the
7352: inodes or the nonzero elements is wanted. For BAIJ matrices the compressed version is
7353: always used.
7354: . n - size of (possibly compressed) matrix
7355: . ia - the row pointers
7356: - ja - the column indices
7358: Output Parameters:
7359: . done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7361: Note:
7362: This routine zeros out n, ia, and ja. This is to prevent accidental
7363: us of the array after it has been restored. If you pass NULL, it will
7364: not zero the pointers. Use of ia or ja after MatRestoreRowIJ() is invalid.
7366: Level: developer
7368: .seealso: MatGetRowIJ(), MatRestoreColumnIJ()
7369: @*/
7370: PetscErrorCode MatRestoreRowIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7371: {
7380: MatCheckPreallocated(mat,1);
7382: if (!mat->ops->restorerowij) *done = PETSC_FALSE;
7383: else {
7384: *done = PETSC_TRUE;
7385: (*mat->ops->restorerowij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7386: if (n) *n = 0;
7387: if (ia) *ia = NULL;
7388: if (ja) *ja = NULL;
7389: }
7390: return(0);
7391: }
7395: /*@C
7396: MatRestoreColumnIJ - Call after you are completed with the ia,ja indices obtained with
7397: MatGetColumnIJ().
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.
7410: Output Parameters:
7411: + n - size of (possibly compressed) matrix
7412: . ia - the column pointers
7413: . ja - the row indices
7414: - done - PETSC_TRUE or PETSC_FALSE indicated that the values have been returned
7416: Level: developer
7418: .seealso: MatGetColumnIJ(), MatRestoreRowIJ()
7419: @*/
7420: PetscErrorCode MatRestoreColumnIJ(Mat mat,PetscInt shift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscBool *done)
7421: {
7430: MatCheckPreallocated(mat,1);
7432: if (!mat->ops->restorecolumnij) *done = PETSC_FALSE;
7433: else {
7434: *done = PETSC_TRUE;
7435: (*mat->ops->restorecolumnij)(mat,shift,symmetric,inodecompressed,n,ia,ja,done);
7436: if (n) *n = 0;
7437: if (ia) *ia = NULL;
7438: if (ja) *ja = NULL;
7439: }
7440: return(0);
7441: }
7445: /*@C
7446: MatColoringPatch -Used inside matrix coloring routines that
7447: use MatGetRowIJ() and/or MatGetColumnIJ().
7449: Collective on Mat
7451: Input Parameters:
7452: + mat - the matrix
7453: . ncolors - max color value
7454: . n - number of entries in colorarray
7455: - colorarray - array indicating color for each column
7457: Output Parameters:
7458: . iscoloring - coloring generated using colorarray information
7460: Level: developer
7462: .seealso: MatGetRowIJ(), MatGetColumnIJ()
7464: @*/
7465: PetscErrorCode MatColoringPatch(Mat mat,PetscInt ncolors,PetscInt n,ISColoringValue colorarray[],ISColoring *iscoloring)
7466: {
7474: MatCheckPreallocated(mat,1);
7476: if (!mat->ops->coloringpatch) {
7477: ISColoringCreate(PetscObjectComm((PetscObject)mat),ncolors,n,colorarray,PETSC_OWN_POINTER,iscoloring);
7478: } else {
7479: (*mat->ops->coloringpatch)(mat,ncolors,n,colorarray,iscoloring);
7480: }
7481: return(0);
7482: }
7487: /*@
7488: MatSetUnfactored - Resets a factored matrix to be treated as unfactored.
7490: Logically Collective on Mat
7492: Input Parameter:
7493: . mat - the factored matrix to be reset
7495: Notes:
7496: This routine should be used only with factored matrices formed by in-place
7497: factorization via ILU(0) (or by in-place LU factorization for the MATSEQDENSE
7498: format). This option can save memory, for example, when solving nonlinear
7499: systems with a matrix-free Newton-Krylov method and a matrix-based, in-place
7500: ILU(0) preconditioner.
7502: Note that one can specify in-place ILU(0) factorization by calling
7503: .vb
7504: PCType(pc,PCILU);
7505: PCFactorSeUseInPlace(pc);
7506: .ve
7507: or by using the options -pc_type ilu -pc_factor_in_place
7509: In-place factorization ILU(0) can also be used as a local
7510: solver for the blocks within the block Jacobi or additive Schwarz
7511: methods (runtime option: -sub_pc_factor_in_place). See Users-Manual: ch_pc
7512: for details on setting local solver options.
7514: Most users should employ the simplified KSP interface for linear solvers
7515: instead of working directly with matrix algebra routines such as this.
7516: See, e.g., KSPCreate().
7518: Level: developer
7520: .seealso: PCFactorSetUseInPlace(), PCFactorGetUseInPlace()
7522: Concepts: matrices^unfactored
7524: @*/
7525: PetscErrorCode MatSetUnfactored(Mat mat)
7526: {
7532: MatCheckPreallocated(mat,1);
7533: mat->factortype = MAT_FACTOR_NONE;
7534: if (!mat->ops->setunfactored) return(0);
7535: (*mat->ops->setunfactored)(mat);
7536: return(0);
7537: }
7539: /*MC
7540: MatDenseGetArrayF90 - Accesses a matrix array from Fortran90.
7542: Synopsis:
7543: MatDenseGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7545: Not collective
7547: Input Parameter:
7548: . x - matrix
7550: Output Parameters:
7551: + xx_v - the Fortran90 pointer to the array
7552: - ierr - error code
7554: Example of Usage:
7555: .vb
7556: PetscScalar, pointer xx_v(:,:)
7557: ....
7558: call MatDenseGetArrayF90(x,xx_v,ierr)
7559: a = xx_v(3)
7560: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7561: .ve
7563: Level: advanced
7565: .seealso: MatDenseRestoreArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJGetArrayF90()
7567: Concepts: matrices^accessing array
7569: M*/
7571: /*MC
7572: MatDenseRestoreArrayF90 - Restores a matrix array that has been
7573: accessed with MatDenseGetArrayF90().
7575: Synopsis:
7576: MatDenseRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:,:)},integer ierr)
7578: Not collective
7580: Input Parameters:
7581: + x - matrix
7582: - xx_v - the Fortran90 pointer to the array
7584: Output Parameter:
7585: . ierr - error code
7587: Example of Usage:
7588: .vb
7589: PetscScalar, pointer xx_v(:,:)
7590: ....
7591: call MatDenseGetArrayF90(x,xx_v,ierr)
7592: a = xx_v(3)
7593: call MatDenseRestoreArrayF90(x,xx_v,ierr)
7594: .ve
7596: Level: advanced
7598: .seealso: MatDenseGetArrayF90(), MatDenseGetArray(), MatDenseRestoreArray(), MatSeqAIJRestoreArrayF90()
7600: M*/
7603: /*MC
7604: MatSeqAIJGetArrayF90 - Accesses a matrix array from Fortran90.
7606: Synopsis:
7607: MatSeqAIJGetArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7609: Not collective
7611: Input Parameter:
7612: . x - matrix
7614: Output Parameters:
7615: + xx_v - the Fortran90 pointer to the array
7616: - ierr - error code
7618: Example of Usage:
7619: .vb
7620: PetscScalar, pointer xx_v(:)
7621: ....
7622: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7623: a = xx_v(3)
7624: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7625: .ve
7627: Level: advanced
7629: .seealso: MatSeqAIJRestoreArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseGetArrayF90()
7631: Concepts: matrices^accessing array
7633: M*/
7635: /*MC
7636: MatSeqAIJRestoreArrayF90 - Restores a matrix array that has been
7637: accessed with MatSeqAIJGetArrayF90().
7639: Synopsis:
7640: MatSeqAIJRestoreArrayF90(Mat x,{Scalar, pointer :: xx_v(:)},integer ierr)
7642: Not collective
7644: Input Parameters:
7645: + x - matrix
7646: - xx_v - the Fortran90 pointer to the array
7648: Output Parameter:
7649: . ierr - error code
7651: Example of Usage:
7652: .vb
7653: PetscScalar, pointer xx_v(:)
7654: ....
7655: call MatSeqAIJGetArrayF90(x,xx_v,ierr)
7656: a = xx_v(3)
7657: call MatSeqAIJRestoreArrayF90(x,xx_v,ierr)
7658: .ve
7660: Level: advanced
7662: .seealso: MatSeqAIJGetArrayF90(), MatSeqAIJGetArray(), MatSeqAIJRestoreArray(), MatDenseRestoreArrayF90()
7664: M*/
7669: /*@
7670: MatGetSubMatrix - Gets a single submatrix on the same number of processors
7671: as the original matrix.
7673: Collective on Mat
7675: Input Parameters:
7676: + mat - the original matrix
7677: . isrow - parallel IS containing the rows this processor should obtain
7678: . 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.
7679: - cll - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
7681: Output Parameter:
7682: . newmat - the new submatrix, of the same type as the old
7684: Level: advanced
7686: Notes:
7687: The submatrix will be able to be multiplied with vectors using the same layout as iscol.
7689: Some matrix types place restrictions on the row and column indices, such
7690: as that they be sorted or that they be equal to each other.
7692: The index sets may not have duplicate entries.
7694: The first time this is called you should use a cll of MAT_INITIAL_MATRIX,
7695: the MatGetSubMatrix() routine will create the newmat for you. Any additional calls
7696: to this routine with a mat of the same nonzero structure and with a call of MAT_REUSE_MATRIX
7697: will reuse the matrix generated the first time. You should call MatDestroy() on newmat when
7698: you are finished using it.
7700: The communicator of the newly obtained matrix is ALWAYS the same as the communicator of
7701: the input matrix.
7703: If iscol is NULL then all columns are obtained (not supported in Fortran).
7705: Example usage:
7706: Consider the following 8x8 matrix with 34 non-zero values, that is
7707: assembled across 3 processors. Let's assume that proc0 owns 3 rows,
7708: proc1 owns 3 rows, proc2 owns 2 rows. This division can be shown
7709: as follows:
7711: .vb
7712: 1 2 0 | 0 3 0 | 0 4
7713: Proc0 0 5 6 | 7 0 0 | 8 0
7714: 9 0 10 | 11 0 0 | 12 0
7715: -------------------------------------
7716: 13 0 14 | 15 16 17 | 0 0
7717: Proc1 0 18 0 | 19 20 21 | 0 0
7718: 0 0 0 | 22 23 0 | 24 0
7719: -------------------------------------
7720: Proc2 25 26 27 | 0 0 28 | 29 0
7721: 30 0 0 | 31 32 33 | 0 34
7722: .ve
7724: Suppose isrow = [0 1 | 4 | 6 7] and iscol = [1 2 | 3 4 5 | 6]. The resulting submatrix is
7726: .vb
7727: 2 0 | 0 3 0 | 0
7728: Proc0 5 6 | 7 0 0 | 8
7729: -------------------------------
7730: Proc1 18 0 | 19 20 21 | 0
7731: -------------------------------
7732: Proc2 26 27 | 0 0 28 | 29
7733: 0 0 | 31 32 33 | 0
7734: .ve
7737: Concepts: matrices^submatrices
7739: .seealso: MatGetSubMatrices()
7740: @*/
7741: PetscErrorCode MatGetSubMatrix(Mat mat,IS isrow,IS iscol,MatReuse cll,Mat *newmat)
7742: {
7744: PetscMPIInt size;
7745: Mat *local;
7746: IS iscoltmp;
7755: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
7756: if (cll == MAT_IGNORE_MATRIX) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Cannot use MAT_IGNORE_MATRIX");
7758: MatCheckPreallocated(mat,1);
7759: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
7761: if (!iscol || isrow == iscol) {
7762: PetscBool stride;
7763: PetscMPIInt grabentirematrix = 0,grab;
7764: PetscObjectTypeCompare((PetscObject)isrow,ISSTRIDE,&stride);
7765: if (stride) {
7766: PetscInt first,step,n,rstart,rend;
7767: ISStrideGetInfo(isrow,&first,&step);
7768: if (step == 1) {
7769: MatGetOwnershipRange(mat,&rstart,&rend);
7770: if (rstart == first) {
7771: ISGetLocalSize(isrow,&n);
7772: if (n == rend-rstart) {
7773: grabentirematrix = 1;
7774: }
7775: }
7776: }
7777: }
7778: MPIU_Allreduce(&grabentirematrix,&grab,1,MPI_INT,MPI_MIN,PetscObjectComm((PetscObject)mat));
7779: if (grab) {
7780: PetscInfo(mat,"Getting entire matrix as submatrix\n");
7781: if (cll == MAT_INITIAL_MATRIX) {
7782: *newmat = mat;
7783: PetscObjectReference((PetscObject)mat);
7784: }
7785: return(0);
7786: }
7787: }
7789: if (!iscol) {
7790: ISCreateStride(PetscObjectComm((PetscObject)mat),mat->cmap->n,mat->cmap->rstart,1,&iscoltmp);
7791: } else {
7792: iscoltmp = iscol;
7793: }
7795: /* if original matrix is on just one processor then use submatrix generated */
7796: if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1 && cll == MAT_REUSE_MATRIX) {
7797: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_REUSE_MATRIX,&newmat);
7798: if (!iscol) {ISDestroy(&iscoltmp);}
7799: return(0);
7800: } else if (mat->ops->getsubmatrices && !mat->ops->getsubmatrix && size == 1) {
7801: MatGetSubMatrices(mat,1,&isrow,&iscoltmp,MAT_INITIAL_MATRIX,&local);
7802: *newmat = *local;
7803: PetscFree(local);
7804: if (!iscol) {ISDestroy(&iscoltmp);}
7805: return(0);
7806: } else if (!mat->ops->getsubmatrix) {
7807: /* Create a new matrix type that implements the operation using the full matrix */
7808: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7809: switch (cll) {
7810: case MAT_INITIAL_MATRIX:
7811: MatCreateSubMatrix(mat,isrow,iscoltmp,newmat);
7812: break;
7813: case MAT_REUSE_MATRIX:
7814: MatSubMatrixUpdate(*newmat,mat,isrow,iscoltmp);
7815: break;
7816: default: SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"Invalid MatReuse, must be either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX");
7817: }
7818: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7819: if (!iscol) {ISDestroy(&iscoltmp);}
7820: return(0);
7821: }
7823: if (!mat->ops->getsubmatrix) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
7824: PetscLogEventBegin(MAT_GetSubMatrix,mat,0,0,0);
7825: (*mat->ops->getsubmatrix)(mat,isrow,iscoltmp,cll,newmat);
7826: PetscLogEventEnd(MAT_GetSubMatrix,mat,0,0,0);
7827: if (!iscol) {ISDestroy(&iscoltmp);}
7828: if (*newmat && cll == MAT_INITIAL_MATRIX) {PetscObjectStateIncrease((PetscObject)*newmat);}
7829: return(0);
7830: }
7834: /*@
7835: MatStashSetInitialSize - sets the sizes of the matrix stash, that is
7836: used during the assembly process to store values that belong to
7837: other processors.
7839: Not Collective
7841: Input Parameters:
7842: + mat - the matrix
7843: . size - the initial size of the stash.
7844: - bsize - the initial size of the block-stash(if used).
7846: Options Database Keys:
7847: + -matstash_initial_size <size> or <size0,size1,...sizep-1>
7848: - -matstash_block_initial_size <bsize> or <bsize0,bsize1,...bsizep-1>
7850: Level: intermediate
7852: Notes:
7853: The block-stash is used for values set with MatSetValuesBlocked() while
7854: the stash is used for values set with MatSetValues()
7856: Run with the option -info and look for output of the form
7857: MatAssemblyBegin_MPIXXX:Stash has MM entries, uses nn mallocs.
7858: to determine the appropriate value, MM, to use for size and
7859: MatAssemblyBegin_MPIXXX:Block-Stash has BMM entries, uses nn mallocs.
7860: to determine the value, BMM to use for bsize
7862: Concepts: stash^setting matrix size
7863: Concepts: matrices^stash
7865: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashGetInfo()
7867: @*/
7868: PetscErrorCode MatStashSetInitialSize(Mat mat,PetscInt size, PetscInt bsize)
7869: {
7875: MatStashSetInitialSize_Private(&mat->stash,size);
7876: MatStashSetInitialSize_Private(&mat->bstash,bsize);
7877: return(0);
7878: }
7882: /*@
7883: MatInterpolateAdd - w = y + A*x or A'*x depending on the shape of
7884: the matrix
7886: Neighbor-wise Collective on Mat
7888: Input Parameters:
7889: + mat - the matrix
7890: . x,y - the vectors
7891: - w - where the result is stored
7893: Level: intermediate
7895: Notes:
7896: w may be the same vector as y.
7898: This allows one to use either the restriction or interpolation (its transpose)
7899: matrix to do the interpolation
7901: Concepts: interpolation
7903: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7905: @*/
7906: PetscErrorCode MatInterpolateAdd(Mat A,Vec x,Vec y,Vec w)
7907: {
7909: PetscInt M,N,Ny;
7917: MatCheckPreallocated(A,1);
7918: MatGetSize(A,&M,&N);
7919: VecGetSize(y,&Ny);
7920: if (M == Ny) {
7921: MatMultAdd(A,x,y,w);
7922: } else {
7923: MatMultTransposeAdd(A,x,y,w);
7924: }
7925: return(0);
7926: }
7930: /*@
7931: MatInterpolate - y = A*x or A'*x depending on the shape of
7932: the matrix
7934: Neighbor-wise Collective on Mat
7936: Input Parameters:
7937: + mat - the matrix
7938: - x,y - the vectors
7940: Level: intermediate
7942: Notes:
7943: This allows one to use either the restriction or interpolation (its transpose)
7944: matrix to do the interpolation
7946: Concepts: matrices^interpolation
7948: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatRestrict()
7950: @*/
7951: PetscErrorCode MatInterpolate(Mat A,Vec x,Vec y)
7952: {
7954: PetscInt M,N,Ny;
7961: MatCheckPreallocated(A,1);
7962: MatGetSize(A,&M,&N);
7963: VecGetSize(y,&Ny);
7964: if (M == Ny) {
7965: MatMult(A,x,y);
7966: } else {
7967: MatMultTranspose(A,x,y);
7968: }
7969: return(0);
7970: }
7974: /*@
7975: MatRestrict - y = A*x or A'*x
7977: Neighbor-wise Collective on Mat
7979: Input Parameters:
7980: + mat - the matrix
7981: - x,y - the vectors
7983: Level: intermediate
7985: Notes:
7986: This allows one to use either the restriction or interpolation (its transpose)
7987: matrix to do the restriction
7989: Concepts: matrices^restriction
7991: .seealso: MatMultAdd(), MatMultTransposeAdd(), MatInterpolate()
7993: @*/
7994: PetscErrorCode MatRestrict(Mat A,Vec x,Vec y)
7995: {
7997: PetscInt M,N,Ny;
8004: MatCheckPreallocated(A,1);
8006: MatGetSize(A,&M,&N);
8007: VecGetSize(y,&Ny);
8008: if (M == Ny) {
8009: MatMult(A,x,y);
8010: } else {
8011: MatMultTranspose(A,x,y);
8012: }
8013: return(0);
8014: }
8018: /*@
8019: MatGetNullSpace - retrieves the null space to a matrix.
8021: Logically Collective on Mat and MatNullSpace
8023: Input Parameters:
8024: + mat - the matrix
8025: - nullsp - the null space object
8027: Level: developer
8029: Concepts: null space^attaching to matrix
8031: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetNullSpace()
8032: @*/
8033: PetscErrorCode MatGetNullSpace(Mat mat, MatNullSpace *nullsp)
8034: {
8039: *nullsp = mat->nullsp;
8040: return(0);
8041: }
8045: /*@
8046: MatSetNullSpace - attaches a null space to a matrix.
8048: Logically Collective on Mat and MatNullSpace
8050: Input Parameters:
8051: + mat - the matrix
8052: - nullsp - the null space object
8054: Level: advanced
8056: Notes:
8057: This null space is used by the linear solvers. Overwrites any previous null space that may have been attached
8059: For inconsistent singular systems (linear systems where the right hand side is not in the range of the operator) you also likely should
8060: call MatSetTransposeNullSpace(). This allows the linear system to be solved in a least squares sense.
8062: You can remove the null space by calling this routine with an nullsp of NULL
8065: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8066: 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).
8067: 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
8068: 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
8069: 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).
8071: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8073: Concepts: null space^attaching to matrix
8075: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetTransposeNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8076: @*/
8077: PetscErrorCode MatSetNullSpace(Mat mat,MatNullSpace nullsp)
8078: {
8085: MatCheckPreallocated(mat,1);
8086: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8087: MatNullSpaceDestroy(&mat->nullsp);
8088: mat->nullsp = nullsp;
8089: return(0);
8090: }
8094: /*@
8095: MatGetTransposeNullSpace - retrieves the null space of the transpose of a matrix.
8097: Logically Collective on Mat and MatNullSpace
8099: Input Parameters:
8100: + mat - the matrix
8101: - nullsp - the null space object
8103: Level: developer
8105: Concepts: null space^attaching to matrix
8107: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatSetTransposeNullSpace(), MatSetNullSpace(), MatGetNullSpace()
8108: @*/
8109: PetscErrorCode MatGetTransposeNullSpace(Mat mat, MatNullSpace *nullsp)
8110: {
8115: *nullsp = mat->transnullsp;
8116: return(0);
8117: }
8121: /*@
8122: MatSetTransposeNullSpace - attaches a null space to a matrix.
8124: Logically Collective on Mat and MatNullSpace
8126: Input Parameters:
8127: + mat - the matrix
8128: - nullsp - the null space object
8130: Level: advanced
8132: Notes:
8133: 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.
8134: You must also call MatSetNullSpace()
8137: The fundamental theorem of linear algebra (Gilbert Strang, Introduction to Applied Mathematics, page 72) states that
8138: 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).
8139: 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
8140: 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
8141: 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).
8143: Krylov solvers can produce the minimal norm solution to the least squares problem by utilizing MatNullSpaceRemove().
8145: Concepts: null space^attaching to matrix
8147: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNearNullSpace(), MatGetNullSpace(), MatSetNullSpace(), MatGetTransposeNullSpace(), MatNullSpaceRemove()
8148: @*/
8149: PetscErrorCode MatSetTransposeNullSpace(Mat mat,MatNullSpace nullsp)
8150: {
8157: MatCheckPreallocated(mat,1);
8158: PetscObjectReference((PetscObject)nullsp);
8159: MatNullSpaceDestroy(&mat->transnullsp);
8160: mat->transnullsp = nullsp;
8161: return(0);
8162: }
8166: /*@
8167: MatSetNearNullSpace - attaches a null space to a matrix, which is often the null space (rigid body modes) of the operator without boundary conditions
8168: This null space will be used to provide near null space vectors to a multigrid preconditioner built from this matrix.
8170: Logically Collective on Mat and MatNullSpace
8172: Input Parameters:
8173: + mat - the matrix
8174: - nullsp - the null space object
8176: Level: advanced
8178: Notes:
8179: Overwrites any previous near null space that may have been attached
8181: You can remove the null space by calling this routine with an nullsp of NULL
8183: Concepts: null space^attaching to matrix
8185: .seealso: MatCreate(), MatNullSpaceCreate(), MatSetNullSpace(), MatNullSpaceCreateRigidBody(), MatGetNearNullSpace()
8186: @*/
8187: PetscErrorCode MatSetNearNullSpace(Mat mat,MatNullSpace nullsp)
8188: {
8195: MatCheckPreallocated(mat,1);
8196: if (nullsp) {PetscObjectReference((PetscObject)nullsp);}
8197: MatNullSpaceDestroy(&mat->nearnullsp);
8198: mat->nearnullsp = nullsp;
8199: return(0);
8200: }
8204: /*@
8205: MatGetNearNullSpace -Get null space attached with MatSetNearNullSpace()
8207: Not Collective
8209: Input Parameters:
8210: . mat - the matrix
8212: Output Parameters:
8213: . nullsp - the null space object, NULL if not set
8215: Level: developer
8217: Concepts: null space^attaching to matrix
8219: .seealso: MatSetNearNullSpace(), MatGetNullSpace(), MatNullSpaceCreate()
8220: @*/
8221: PetscErrorCode MatGetNearNullSpace(Mat mat,MatNullSpace *nullsp)
8222: {
8227: MatCheckPreallocated(mat,1);
8228: *nullsp = mat->nearnullsp;
8229: return(0);
8230: }
8234: /*@C
8235: MatICCFactor - Performs in-place incomplete Cholesky factorization of matrix.
8237: Collective on Mat
8239: Input Parameters:
8240: + mat - the matrix
8241: . row - row/column permutation
8242: . fill - expected fill factor >= 1.0
8243: - level - level of fill, for ICC(k)
8245: Notes:
8246: Probably really in-place only when level of fill is zero, otherwise allocates
8247: new space to store factored matrix and deletes previous memory.
8249: Most users should employ the simplified KSP interface for linear solvers
8250: instead of working directly with matrix algebra routines such as this.
8251: See, e.g., KSPCreate().
8253: Level: developer
8255: Concepts: matrices^incomplete Cholesky factorization
8256: Concepts: Cholesky factorization
8258: .seealso: MatICCFactorSymbolic(), MatLUFactorNumeric(), MatCholeskyFactor()
8260: Developer Note: fortran interface is not autogenerated as the f90
8261: interface defintion cannot be generated correctly [due to MatFactorInfo]
8263: @*/
8264: PetscErrorCode MatICCFactor(Mat mat,IS row,const MatFactorInfo *info)
8265: {
8273: if (mat->rmap->N != mat->cmap->N) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"matrix must be square");
8274: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
8275: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
8276: if (!mat->ops->iccfactor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8277: MatCheckPreallocated(mat,1);
8278: (*mat->ops->iccfactor)(mat,row,info);
8279: PetscObjectStateIncrease((PetscObject)mat);
8280: return(0);
8281: }
8285: /*@
8286: MatSetValuesAdifor - Sets values computed with automatic differentiation into a matrix.
8288: Not Collective
8290: Input Parameters:
8291: + mat - the matrix
8292: . nl - leading dimension of v
8293: - v - the values compute with ADIFOR
8295: Level: developer
8297: Notes:
8298: Must call MatSetColoring() before using this routine. Also this matrix must already
8299: have its nonzero pattern determined.
8301: .seealso: MatSetOption(), MatAssemblyBegin(), MatAssemblyEnd(), MatSetValuesBlocked(), MatSetValuesLocal(),
8302: MatSetValues(), MatSetColoring()
8303: @*/
8304: PetscErrorCode MatSetValuesAdifor(Mat mat,PetscInt nl,void *v)
8305: {
8313: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8314: PetscLogEventBegin(MAT_SetValues,mat,0,0,0);
8315: if (!mat->ops->setvaluesadifor) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8316: (*mat->ops->setvaluesadifor)(mat,nl,v);
8317: PetscLogEventEnd(MAT_SetValues,mat,0,0,0);
8318: PetscObjectStateIncrease((PetscObject)mat);
8319: return(0);
8320: }
8324: /*@
8325: MatDiagonalScaleLocal - Scales columns of a matrix given the scaling values including the
8326: ghosted ones.
8328: Not Collective
8330: Input Parameters:
8331: + mat - the matrix
8332: - diag = the diagonal values, including ghost ones
8334: Level: developer
8336: Notes: Works only for MPIAIJ and MPIBAIJ matrices
8338: .seealso: MatDiagonalScale()
8339: @*/
8340: PetscErrorCode MatDiagonalScaleLocal(Mat mat,Vec diag)
8341: {
8343: PetscMPIInt size;
8350: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must be already assembled");
8351: PetscLogEventBegin(MAT_Scale,mat,0,0,0);
8352: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
8353: if (size == 1) {
8354: PetscInt n,m;
8355: VecGetSize(diag,&n);
8356: MatGetSize(mat,0,&m);
8357: if (m == n) {
8358: MatDiagonalScale(mat,0,diag);
8359: } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only supported for sequential matrices when no ghost points/periodic conditions");
8360: } else {
8361: PetscUseMethod(mat,"MatDiagonalScaleLocal_C",(Mat,Vec),(mat,diag));
8362: }
8363: PetscLogEventEnd(MAT_Scale,mat,0,0,0);
8364: PetscObjectStateIncrease((PetscObject)mat);
8365: return(0);
8366: }
8370: /*@
8371: MatGetInertia - Gets the inertia from a factored matrix
8373: Collective on Mat
8375: Input Parameter:
8376: . mat - the matrix
8378: Output Parameters:
8379: + nneg - number of negative eigenvalues
8380: . nzero - number of zero eigenvalues
8381: - npos - number of positive eigenvalues
8383: Level: advanced
8385: Notes: Matrix must have been factored by MatCholeskyFactor()
8388: @*/
8389: PetscErrorCode MatGetInertia(Mat mat,PetscInt *nneg,PetscInt *nzero,PetscInt *npos)
8390: {
8396: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8397: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Numeric factor mat is not assembled");
8398: if (!mat->ops->getinertia) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8399: (*mat->ops->getinertia)(mat,nneg,nzero,npos);
8400: return(0);
8401: }
8403: /* ----------------------------------------------------------------*/
8406: /*@C
8407: MatSolves - Solves A x = b, given a factored matrix, for a collection of vectors
8409: Neighbor-wise Collective on Mat and Vecs
8411: Input Parameters:
8412: + mat - the factored matrix
8413: - b - the right-hand-side vectors
8415: Output Parameter:
8416: . x - the result vectors
8418: Notes:
8419: The vectors b and x cannot be the same. I.e., one cannot
8420: call MatSolves(A,x,x).
8422: Notes:
8423: Most users should employ the simplified KSP interface for linear solvers
8424: instead of working directly with matrix algebra routines such as this.
8425: See, e.g., KSPCreate().
8427: Level: developer
8429: Concepts: matrices^triangular solves
8431: .seealso: MatSolveAdd(), MatSolveTranspose(), MatSolveTransposeAdd(), MatSolve()
8432: @*/
8433: PetscErrorCode MatSolves(Mat mat,Vecs b,Vecs x)
8434: {
8440: if (x == b) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_IDN,"x and b must be different vectors");
8441: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Unfactored matrix");
8442: if (!mat->rmap->N && !mat->cmap->N) return(0);
8444: if (!mat->ops->solves) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)mat)->type_name);
8445: MatCheckPreallocated(mat,1);
8446: PetscLogEventBegin(MAT_Solves,mat,0,0,0);
8447: (*mat->ops->solves)(mat,b,x);
8448: PetscLogEventEnd(MAT_Solves,mat,0,0,0);
8449: return(0);
8450: }
8454: /*@
8455: MatIsSymmetric - Test whether a matrix is symmetric
8457: Collective on Mat
8459: Input Parameter:
8460: + A - the matrix to test
8461: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact transpose)
8463: Output Parameters:
8464: . flg - the result
8466: Notes: For real numbers MatIsSymmetric() and MatIsHermitian() return identical results
8468: Level: intermediate
8470: Concepts: matrix^symmetry
8472: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetricKnown()
8473: @*/
8474: PetscErrorCode MatIsSymmetric(Mat A,PetscReal tol,PetscBool *flg)
8475: {
8482: if (!A->symmetric_set) {
8483: if (!A->ops->issymmetric) {
8484: MatType mattype;
8485: MatGetType(A,&mattype);
8486: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8487: }
8488: (*A->ops->issymmetric)(A,tol,flg);
8489: if (!tol) {
8490: A->symmetric_set = PETSC_TRUE;
8491: A->symmetric = *flg;
8492: if (A->symmetric) {
8493: A->structurally_symmetric_set = PETSC_TRUE;
8494: A->structurally_symmetric = PETSC_TRUE;
8495: }
8496: }
8497: } else if (A->symmetric) {
8498: *flg = PETSC_TRUE;
8499: } else if (!tol) {
8500: *flg = PETSC_FALSE;
8501: } else {
8502: if (!A->ops->issymmetric) {
8503: MatType mattype;
8504: MatGetType(A,&mattype);
8505: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for symmetric",mattype);
8506: }
8507: (*A->ops->issymmetric)(A,tol,flg);
8508: }
8509: return(0);
8510: }
8514: /*@
8515: MatIsHermitian - Test whether a matrix is Hermitian
8517: Collective on Mat
8519: Input Parameter:
8520: + A - the matrix to test
8521: - tol - difference between value and its transpose less than this amount counts as equal (use 0.0 for exact Hermitian)
8523: Output Parameters:
8524: . flg - the result
8526: Level: intermediate
8528: Concepts: matrix^symmetry
8530: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(),
8531: MatIsSymmetricKnown(), MatIsSymmetric()
8532: @*/
8533: PetscErrorCode MatIsHermitian(Mat A,PetscReal tol,PetscBool *flg)
8534: {
8541: if (!A->hermitian_set) {
8542: if (!A->ops->ishermitian) {
8543: MatType mattype;
8544: MatGetType(A,&mattype);
8545: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8546: }
8547: (*A->ops->ishermitian)(A,tol,flg);
8548: if (!tol) {
8549: A->hermitian_set = PETSC_TRUE;
8550: A->hermitian = *flg;
8551: if (A->hermitian) {
8552: A->structurally_symmetric_set = PETSC_TRUE;
8553: A->structurally_symmetric = PETSC_TRUE;
8554: }
8555: }
8556: } else if (A->hermitian) {
8557: *flg = PETSC_TRUE;
8558: } else if (!tol) {
8559: *flg = PETSC_FALSE;
8560: } else {
8561: if (!A->ops->ishermitian) {
8562: MatType mattype;
8563: MatGetType(A,&mattype);
8564: SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Matrix of type <%s> does not support checking for hermitian",mattype);
8565: }
8566: (*A->ops->ishermitian)(A,tol,flg);
8567: }
8568: return(0);
8569: }
8573: /*@
8574: MatIsSymmetricKnown - Checks the flag on the matrix to see if it is symmetric.
8576: Not Collective
8578: Input Parameter:
8579: . A - the matrix to check
8581: Output Parameters:
8582: + set - if the symmetric flag is set (this tells you if the next flag is valid)
8583: - flg - the result
8585: Level: advanced
8587: Concepts: matrix^symmetry
8589: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsSymmetric()
8590: if you want it explicitly checked
8592: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8593: @*/
8594: PetscErrorCode MatIsSymmetricKnown(Mat A,PetscBool *set,PetscBool *flg)
8595: {
8600: if (A->symmetric_set) {
8601: *set = PETSC_TRUE;
8602: *flg = A->symmetric;
8603: } else {
8604: *set = PETSC_FALSE;
8605: }
8606: return(0);
8607: }
8611: /*@
8612: MatIsHermitianKnown - Checks the flag on the matrix to see if it is hermitian.
8614: Not Collective
8616: Input Parameter:
8617: . A - the matrix to check
8619: Output Parameters:
8620: + set - if the hermitian flag is set (this tells you if the next flag is valid)
8621: - flg - the result
8623: Level: advanced
8625: Concepts: matrix^symmetry
8627: Note: Does not check the matrix values directly, so this may return unknown (set = PETSC_FALSE). Use MatIsHermitian()
8628: if you want it explicitly checked
8630: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsStructurallySymmetric(), MatSetOption(), MatIsSymmetric()
8631: @*/
8632: PetscErrorCode MatIsHermitianKnown(Mat A,PetscBool *set,PetscBool *flg)
8633: {
8638: if (A->hermitian_set) {
8639: *set = PETSC_TRUE;
8640: *flg = A->hermitian;
8641: } else {
8642: *set = PETSC_FALSE;
8643: }
8644: return(0);
8645: }
8649: /*@
8650: MatIsStructurallySymmetric - Test whether a matrix is structurally symmetric
8652: Collective on Mat
8654: Input Parameter:
8655: . A - the matrix to test
8657: Output Parameters:
8658: . flg - the result
8660: Level: intermediate
8662: Concepts: matrix^symmetry
8664: .seealso: MatTranspose(), MatIsTranspose(), MatIsHermitian(), MatIsSymmetric(), MatSetOption()
8665: @*/
8666: PetscErrorCode MatIsStructurallySymmetric(Mat A,PetscBool *flg)
8667: {
8673: if (!A->structurally_symmetric_set) {
8674: if (!A->ops->isstructurallysymmetric) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix does not support checking for structural symmetric");
8675: (*A->ops->isstructurallysymmetric)(A,&A->structurally_symmetric);
8677: A->structurally_symmetric_set = PETSC_TRUE;
8678: }
8679: *flg = A->structurally_symmetric;
8680: return(0);
8681: }
8685: extern PetscErrorCode MatStashGetInfo_Private(MatStash*,PetscInt*,PetscInt*);
8686: /*@
8687: MatStashGetInfo - Gets how many values are currently in the matrix stash, i.e. need
8688: to be communicated to other processors during the MatAssemblyBegin/End() process
8690: Not collective
8692: Input Parameter:
8693: . vec - the vector
8695: Output Parameters:
8696: + nstash - the size of the stash
8697: . reallocs - the number of additional mallocs incurred.
8698: . bnstash - the size of the block stash
8699: - breallocs - the number of additional mallocs incurred.in the block stash
8701: Level: advanced
8703: .seealso: MatAssemblyBegin(), MatAssemblyEnd(), Mat, MatStashSetInitialSize()
8705: @*/
8706: PetscErrorCode MatStashGetInfo(Mat mat,PetscInt *nstash,PetscInt *reallocs,PetscInt *bnstash,PetscInt *breallocs)
8707: {
8711: MatStashGetInfo_Private(&mat->stash,nstash,reallocs);
8712: MatStashGetInfo_Private(&mat->bstash,bnstash,breallocs);
8713: return(0);
8714: }
8718: /*@C
8719: MatCreateVecs - Get vector(s) compatible with the matrix, i.e. with the same
8720: parallel layout
8722: Collective on Mat
8724: Input Parameter:
8725: . mat - the matrix
8727: Output Parameter:
8728: + right - (optional) vector that the matrix can be multiplied against
8729: - left - (optional) vector that the matrix vector product can be stored in
8731: Notes:
8732: 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().
8734: Notes: These are new vectors which are not owned by the Mat, they should be destroyed in VecDestroy() when no longer needed
8736: Level: advanced
8738: .seealso: MatCreate(), VecDestroy()
8739: @*/
8740: PetscErrorCode MatCreateVecs(Mat mat,Vec *right,Vec *left)
8741: {
8747: if (mat->ops->getvecs) {
8748: (*mat->ops->getvecs)(mat,right,left);
8749: } else {
8750: PetscInt rbs,cbs;
8751: MatGetBlockSizes(mat,&rbs,&cbs);
8752: if (right) {
8753: if (mat->cmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for columns not yet setup");
8754: VecCreate(PetscObjectComm((PetscObject)mat),right);
8755: VecSetSizes(*right,mat->cmap->n,PETSC_DETERMINE);
8756: VecSetBlockSize(*right,cbs);
8757: VecSetType(*right,VECSTANDARD);
8758: PetscLayoutReference(mat->cmap,&(*right)->map);
8759: }
8760: if (left) {
8761: if (mat->rmap->n < 0) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"PetscLayout for rows not yet setup");
8762: VecCreate(PetscObjectComm((PetscObject)mat),left);
8763: VecSetSizes(*left,mat->rmap->n,PETSC_DETERMINE);
8764: VecSetBlockSize(*left,rbs);
8765: VecSetType(*left,VECSTANDARD);
8766: PetscLayoutReference(mat->rmap,&(*left)->map);
8767: }
8768: }
8769: return(0);
8770: }
8774: /*@C
8775: MatFactorInfoInitialize - Initializes a MatFactorInfo data structure
8776: with default values.
8778: Not Collective
8780: Input Parameters:
8781: . info - the MatFactorInfo data structure
8784: Notes: The solvers are generally used through the KSP and PC objects, for example
8785: PCLU, PCILU, PCCHOLESKY, PCICC
8787: Level: developer
8789: .seealso: MatFactorInfo
8791: Developer Note: fortran interface is not autogenerated as the f90
8792: interface defintion cannot be generated correctly [due to MatFactorInfo]
8794: @*/
8796: PetscErrorCode MatFactorInfoInitialize(MatFactorInfo *info)
8797: {
8801: PetscMemzero(info,sizeof(MatFactorInfo));
8802: return(0);
8803: }
8807: /*@
8808: MatFactorSetSchurIS - Set indices corresponding to the Schur complement
8810: Collective on Mat
8812: Input Parameters:
8813: + mat - the factored matrix
8814: - is - the index set defining the Schur indices (0-based)
8816: Notes:
8818: Level: developer
8820: Concepts:
8822: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8824: @*/
8825: PetscErrorCode MatFactorSetSchurIS(Mat mat,IS is)
8826: {
8827: PetscErrorCode ierr,(*f)(Mat,IS);
8835: if (!mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Only for factored matrix");
8836: PetscObjectQueryFunction((PetscObject)mat,"MatFactorSetSchurIS_C",&f);
8837: 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");
8838: (*f)(mat,is);
8839: return(0);
8840: }
8844: /*@
8845: MatFactorCreateSchurComplement - Create a Schur complement matrix object using Schur data computed during the factorization step
8847: Logically Collective on Mat
8849: Input Parameters:
8850: + F - the factored matrix obtained by calling MatGetFactor() from PETSc-MUMPS interface
8851: . *S - location where to return the Schur complement (MATDENSE)
8853: Notes:
8854: The routine provides a copy of the Schur data stored within solver's data strutures. The caller must destroy the object when it is no longer needed.
8855: If MatFactorInvertSchurComplement has been called, the routine gets back the inverse
8857: Level: advanced
8859: References:
8861: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorGetSchurComplement()
8862: @*/
8863: PetscErrorCode MatFactorCreateSchurComplement(Mat F,Mat* S)
8864: {
8869: PetscUseMethod(F,"MatFactorCreateSchurComplement_C",(Mat,Mat*),(F,S));
8870: return(0);
8871: }
8875: /*@
8876: MatFactorGetSchurComplement - Get a Schur complement matrix object using the current Schur data
8878: Logically Collective on Mat
8880: Input Parameters:
8881: + F - the factored matrix obtained by calling MatGetFactor()
8882: . *S - location where to return the Schur complement (in MATDENSE format)
8884: Notes:
8885: Schur complement mode is currently implemented for sequential matrices.
8886: The routine returns a dense matrix pointing to the raw data of the Schur Complement stored within the data strutures of the solver; e.g. if MatFactorInvertSchurComplement has been called, the returned matrix is actually the inverse of the Schur complement.
8887: The caller should call MatFactorRestoreSchurComplement when the object is no longer needed.
8889: Level: advanced
8891: References:
8893: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8894: @*/
8895: PetscErrorCode MatFactorGetSchurComplement(Mat F,Mat* S)
8896: {
8901: PetscUseMethod(F,"MatFactorGetSchurComplement_C",(Mat,Mat*),(F,S));
8902: return(0);
8903: }
8907: /*@
8908: MatFactorRestoreSchurComplement - Restore the Schur complement matrix object obtained from a call to MatFactorGetSchurComplement
8910: Logically Collective on Mat
8912: Input Parameters:
8913: + F - the factored matrix obtained by calling MatGetFactor()
8914: . *S - location where the Schur complement is stored
8916: Notes:
8918: Level: advanced
8920: References:
8922: .seealso: MatGetFactor(), MatFactorSetSchurIS(), MatFactorRestoreSchurComplement(), MatFactorCreateSchurComplement()
8923: @*/
8924: PetscErrorCode MatFactorRestoreSchurComplement(Mat F,Mat* S)
8925: {
8931: MatDestroy(S);
8932: return(0);
8933: }
8937: /*@
8938: MatFactorSolveSchurComplementTranspose - Solve the transpose of the Schur complement system computed during the factorization step
8940: Logically Collective on Mat
8942: Input Parameters:
8943: + F - the factored matrix obtained by calling MatGetFactor()
8944: . rhs - location where the right hand side of the Schur complement system is stored
8945: - sol - location where the solution of the Schur complement system has to be returned
8947: Notes:
8948: The sizes of the vectors should match the size of the Schur complement
8950: Level: advanced
8952: References:
8954: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8955: @*/
8956: PetscErrorCode MatFactorSolveSchurComplementTranspose(Mat F, Vec rhs, Vec sol)
8957: {
8966: PetscUseMethod(F,"MatFactorSolveSchurComplementTranspose_C",(Mat,Vec,Vec),(F,rhs,sol));
8967: return(0);
8968: }
8972: /*@
8973: MatFactorSolveSchurComplement - Solve the Schur complement system computed during the factorization step
8975: Logically Collective on Mat
8977: Input Parameters:
8978: + F - the factored matrix obtained by calling MatGetFactor()
8979: . rhs - location where the right hand side of the Schur complement system is stored
8980: - sol - location where the solution of the Schur complement system has to be returned
8982: Notes:
8983: The sizes of the vectors should match the size of the Schur complement
8985: Level: advanced
8987: References:
8989: .seealso: MatGetFactor(), MatFactorSetSchurIS()
8990: @*/
8991: PetscErrorCode MatFactorSolveSchurComplement(Mat F, Vec rhs, Vec sol)
8992: {
9001: PetscUseMethod(F,"MatFactorSolveSchurComplement_C",(Mat,Vec,Vec),(F,rhs,sol));
9002: return(0);
9003: }
9007: /*@
9008: MatFactorInvertSchurComplement - Invert the raw Schur data computed during the factorization step
9010: Logically Collective on Mat
9012: Input Parameters:
9013: + F - the factored matrix obtained by calling MatGetFactor()
9015: Notes:
9017: Level: advanced
9019: References:
9021: .seealso: MatGetFactor(), MatFactorSetSchurIS()
9022: @*/
9023: PetscErrorCode MatFactorInvertSchurComplement(Mat F)
9024: {
9029: PetscUseMethod(F,"MatFactorInvertSchurComplement_C",(Mat),(F));
9030: return(0);
9031: }
9036: /*@
9037: MatPtAP - Creates the matrix product C = P^T * A * P
9039: Neighbor-wise Collective on Mat
9041: Input Parameters:
9042: + A - the matrix
9043: . P - the projection matrix
9044: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9045: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(P)), use PETSC_DEFAULT if you do not have a good estimate
9046: if the result is a dense matrix this is irrelevent
9048: Output Parameters:
9049: . C - the product matrix
9051: Notes:
9052: C will be created and must be destroyed by the user with MatDestroy().
9054: This routine is currently only implemented for pairs of AIJ matrices and classes
9055: which inherit from AIJ.
9057: Level: intermediate
9059: .seealso: MatPtAPSymbolic(), MatPtAPNumeric(), MatMatMult(), MatRARt()
9060: @*/
9061: PetscErrorCode MatPtAP(Mat A,Mat P,MatReuse scall,PetscReal fill,Mat *C)
9062: {
9064: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9065: PetscErrorCode (*fP)(Mat,Mat,MatReuse,PetscReal,Mat*);
9066: PetscErrorCode (*ptap)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9067: PetscBool viatranspose=PETSC_FALSE,viamatmatmatmult=PETSC_FALSE;
9070: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viatranspose",&viatranspose,NULL);
9071: PetscOptionsGetBool(((PetscObject)A)->options,((PetscObject)A)->prefix,"-matptap_viamatmatmatmult",&viamatmatmatmult,NULL);
9075: MatCheckPreallocated(A,1);
9076: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9077: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9080: MatCheckPreallocated(P,2);
9081: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9082: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9084: 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);
9085: 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);
9086: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9087: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9089: if (scall == MAT_REUSE_MATRIX) {
9092: if (viatranspose || viamatmatmatmult) {
9093: Mat Pt;
9094: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9095: if (viamatmatmatmult) {
9096: MatMatMatMult(Pt,A,P,scall,fill,C);
9097: } else {
9098: Mat AP;
9099: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9100: MatMatMult(Pt,AP,scall,fill,C);
9101: MatDestroy(&AP);
9102: }
9103: MatDestroy(&Pt);
9104: } else {
9105: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9106: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9107: (*(*C)->ops->ptapnumeric)(A,P,*C);
9108: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9109: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9110: }
9111: return(0);
9112: }
9114: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9115: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9117: fA = A->ops->ptap;
9118: fP = P->ops->ptap;
9119: if (fP == fA) {
9120: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatPtAP not supported for A of type %s",((PetscObject)A)->type_name);
9121: ptap = fA;
9122: } else {
9123: /* dispatch based on the type of A and P from their PetscObject's PetscFunctionLists. */
9124: char ptapname[256];
9125: PetscStrcpy(ptapname,"MatPtAP_");
9126: PetscStrcat(ptapname,((PetscObject)A)->type_name);
9127: PetscStrcat(ptapname,"_");
9128: PetscStrcat(ptapname,((PetscObject)P)->type_name);
9129: PetscStrcat(ptapname,"_C"); /* e.g., ptapname = "MatPtAP_seqdense_seqaij_C" */
9130: PetscObjectQueryFunction((PetscObject)P,ptapname,&ptap);
9131: 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);
9132: }
9134: if (viatranspose || viamatmatmatmult) {
9135: Mat Pt;
9136: MatTranspose(P,MAT_INITIAL_MATRIX,&Pt);
9137: if (viamatmatmatmult) {
9138: MatMatMatMult(Pt,A,P,scall,fill,C);
9139: PetscInfo(*C,"MatPtAP via MatMatMatMult\n");
9140: } else {
9141: Mat AP;
9142: MatMatMult(A,P,MAT_INITIAL_MATRIX,fill,&AP);
9143: MatMatMult(Pt,AP,scall,fill,C);
9144: MatDestroy(&AP);
9145: PetscInfo(*C,"MatPtAP via MatTranspose and MatMatMult\n");
9146: }
9147: MatDestroy(&Pt);
9148: } else {
9149: PetscLogEventBegin(MAT_PtAP,A,P,0,0);
9150: (*ptap)(A,P,scall,fill,C);
9151: PetscLogEventEnd(MAT_PtAP,A,P,0,0);
9152: }
9153: return(0);
9154: }
9158: /*@
9159: MatPtAPNumeric - Computes the matrix product C = P^T * A * P
9161: Neighbor-wise Collective on Mat
9163: Input Parameters:
9164: + A - the matrix
9165: - P - the projection matrix
9167: Output Parameters:
9168: . C - the product matrix
9170: Notes:
9171: C must have been created by calling MatPtAPSymbolic and must be destroyed by
9172: the user using MatDeatroy().
9174: This routine is currently only implemented for pairs of AIJ matrices and classes
9175: which inherit from AIJ. C will be of type MATAIJ.
9177: Level: intermediate
9179: .seealso: MatPtAP(), MatPtAPSymbolic(), MatMatMultNumeric()
9180: @*/
9181: PetscErrorCode MatPtAPNumeric(Mat A,Mat P,Mat C)
9182: {
9188: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9189: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9192: MatCheckPreallocated(P,2);
9193: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9194: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9197: MatCheckPreallocated(C,3);
9198: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9199: 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);
9200: 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);
9201: 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);
9202: 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);
9203: MatCheckPreallocated(A,1);
9205: PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);
9206: (*C->ops->ptapnumeric)(A,P,C);
9207: PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);
9208: return(0);
9209: }
9213: /*@
9214: MatPtAPSymbolic - Creates the (i,j) structure of the matrix product C = P^T * A * P
9216: Neighbor-wise Collective on Mat
9218: Input Parameters:
9219: + A - the matrix
9220: - P - the projection matrix
9222: Output Parameters:
9223: . C - the (i,j) structure of the product matrix
9225: Notes:
9226: C will be created and must be destroyed by the user with MatDestroy().
9228: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9229: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9230: this (i,j) structure by calling MatPtAPNumeric().
9232: Level: intermediate
9234: .seealso: MatPtAP(), MatPtAPNumeric(), MatMatMultSymbolic()
9235: @*/
9236: PetscErrorCode MatPtAPSymbolic(Mat A,Mat P,PetscReal fill,Mat *C)
9237: {
9243: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9244: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9245: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9248: MatCheckPreallocated(P,2);
9249: if (!P->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9250: if (P->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9253: 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);
9254: 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);
9255: MatCheckPreallocated(A,1);
9256: PetscLogEventBegin(MAT_PtAPSymbolic,A,P,0,0);
9257: (*A->ops->ptapsymbolic)(A,P,fill,C);
9258: PetscLogEventEnd(MAT_PtAPSymbolic,A,P,0,0);
9260: /* MatSetBlockSize(*C,A->rmap->bs); NO! this is not always true -ma */
9261: return(0);
9262: }
9266: /*@
9267: MatRARt - Creates the matrix product C = R * A * R^T
9269: Neighbor-wise Collective on Mat
9271: Input Parameters:
9272: + A - the matrix
9273: . R - the projection matrix
9274: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9275: - fill - expected fill as ratio of nnz(C)/nnz(A), use PETSC_DEFAULT if you do not have a good estimate
9276: if the result is a dense matrix this is irrelevent
9278: Output Parameters:
9279: . C - the product matrix
9281: Notes:
9282: C will be created and must be destroyed by the user with MatDestroy().
9284: This routine is currently only implemented for pairs of AIJ matrices and classes
9285: which inherit from AIJ.
9287: Level: intermediate
9289: .seealso: MatRARtSymbolic(), MatRARtNumeric(), MatMatMult(), MatPtAP()
9290: @*/
9291: PetscErrorCode MatRARt(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
9292: {
9298: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9299: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9302: MatCheckPreallocated(R,2);
9303: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9304: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9306: 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);
9308: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9309: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9310: MatCheckPreallocated(A,1);
9312: if (!A->ops->rart) {
9313: MatType mattype;
9314: MatGetType(A,&mattype);
9315: SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Matrix of type <%s> does not support RARt",mattype);
9316: }
9317: PetscLogEventBegin(MAT_RARt,A,R,0,0);
9318: (*A->ops->rart)(A,R,scall,fill,C);
9319: PetscLogEventEnd(MAT_RARt,A,R,0,0);
9320: return(0);
9321: }
9325: /*@
9326: MatRARtNumeric - Computes 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
9334: Output Parameters:
9335: . C - the product matrix
9337: Notes:
9338: C must have been created by calling MatRARtSymbolic and must be destroyed by
9339: the user using MatDestroy().
9341: This routine is currently only implemented for pairs of AIJ matrices and classes
9342: which inherit from AIJ. C will be of type MATAIJ.
9344: Level: intermediate
9346: .seealso: MatRARt(), MatRARtSymbolic(), MatMatMultNumeric()
9347: @*/
9348: PetscErrorCode MatRARtNumeric(Mat A,Mat R,Mat C)
9349: {
9355: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9356: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9359: MatCheckPreallocated(R,2);
9360: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9361: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9364: MatCheckPreallocated(C,3);
9365: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9366: 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);
9367: 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);
9368: 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);
9369: 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);
9370: MatCheckPreallocated(A,1);
9372: PetscLogEventBegin(MAT_RARtNumeric,A,R,0,0);
9373: (*A->ops->rartnumeric)(A,R,C);
9374: PetscLogEventEnd(MAT_RARtNumeric,A,R,0,0);
9375: return(0);
9376: }
9380: /*@
9381: MatRARtSymbolic - Creates the (i,j) structure of the matrix product C = R * A * R^T
9383: Neighbor-wise Collective on Mat
9385: Input Parameters:
9386: + A - the matrix
9387: - R - the projection matrix
9389: Output Parameters:
9390: . C - the (i,j) structure of the product matrix
9392: Notes:
9393: C will be created and must be destroyed by the user with MatDestroy().
9395: This routine is currently only implemented for pairs of SeqAIJ matrices and classes
9396: which inherit from SeqAIJ. C will be of type MATSEQAIJ. The product is computed using
9397: this (i,j) structure by calling MatRARtNumeric().
9399: Level: intermediate
9401: .seealso: MatRARt(), MatRARtNumeric(), MatMatMultSymbolic()
9402: @*/
9403: PetscErrorCode MatRARtSymbolic(Mat A,Mat R,PetscReal fill,Mat *C)
9404: {
9410: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9411: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9412: if (fill <1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9415: MatCheckPreallocated(R,2);
9416: if (!R->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9417: if (R->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9420: 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);
9421: 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);
9422: MatCheckPreallocated(A,1);
9423: PetscLogEventBegin(MAT_RARtSymbolic,A,R,0,0);
9424: (*A->ops->rartsymbolic)(A,R,fill,C);
9425: PetscLogEventEnd(MAT_RARtSymbolic,A,R,0,0);
9427: MatSetBlockSizes(*C,PetscAbs(R->rmap->bs),PetscAbs(R->rmap->bs));
9428: return(0);
9429: }
9433: /*@
9434: MatMatMult - Performs Matrix-Matrix Multiplication C=A*B.
9436: Neighbor-wise Collective on Mat
9438: Input Parameters:
9439: + A - the left matrix
9440: . B - the right matrix
9441: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9442: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate
9443: if the result is a dense matrix this is irrelevent
9445: Output Parameters:
9446: . C - the product matrix
9448: Notes:
9449: Unless scall is MAT_REUSE_MATRIX C will be created.
9451: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9453: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9454: actually needed.
9456: If you have many matrices with the same non-zero structure to multiply, you
9457: should either
9458: $ 1) use MAT_REUSE_MATRIX in all calls but the first or
9459: $ 2) call MatMatMultSymbolic() once and then MatMatMultNumeric() for each product needed
9460: 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
9461: with MAT_REUSE_MATRIX, rather than first having MatMatMult() create it for you. You can NEVER do this if the matrix C is sparse.
9463: Level: intermediate
9465: .seealso: MatMatMultSymbolic(), MatMatMultNumeric(), MatTransposeMatMult(), MatMatTransposeMult(), MatPtAP()
9466: @*/
9467: PetscErrorCode MatMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9468: {
9470: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9471: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9472: PetscErrorCode (*mult)(Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9477: MatCheckPreallocated(A,1);
9478: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9479: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9482: MatCheckPreallocated(B,2);
9483: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9484: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9486: 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);
9487: if (scall == MAT_REUSE_MATRIX) {
9490: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9491: PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);
9492: (*(*C)->ops->matmultnumeric)(A,B,*C);
9493: PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);
9494: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9495: return(0);
9496: }
9497: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9498: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9500: fA = A->ops->matmult;
9501: fB = B->ops->matmult;
9502: if (fB == fA) {
9503: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMult not supported for B of type %s",((PetscObject)B)->type_name);
9504: mult = fB;
9505: } else {
9506: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9507: char multname[256];
9508: PetscStrcpy(multname,"MatMatMult_");
9509: PetscStrcat(multname,((PetscObject)A)->type_name);
9510: PetscStrcat(multname,"_");
9511: PetscStrcat(multname,((PetscObject)B)->type_name);
9512: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9513: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9514: 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);
9515: }
9516: PetscLogEventBegin(MAT_MatMult,A,B,0,0);
9517: (*mult)(A,B,scall,fill,C);
9518: PetscLogEventEnd(MAT_MatMult,A,B,0,0);
9519: return(0);
9520: }
9524: /*@
9525: MatMatMultSymbolic - Performs construction, preallocation, and computes the ij structure
9526: of the matrix-matrix product C=A*B. Call this routine before calling MatMatMultNumeric().
9528: Neighbor-wise Collective on Mat
9530: Input Parameters:
9531: + A - the left matrix
9532: . B - the right matrix
9533: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if you do not have a good estimate,
9534: if C is a dense matrix this is irrelevent
9536: Output Parameters:
9537: . C - the product matrix
9539: Notes:
9540: Unless scall is MAT_REUSE_MATRIX C will be created.
9542: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9543: actually needed.
9545: This routine is currently implemented for
9546: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type AIJ
9547: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9548: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9550: Level: intermediate
9552: Developers Note: There are ways to estimate the number of nonzeros in the resulting product, see for example, http://arxiv.org/abs/1006.4173
9553: We should incorporate them into PETSc.
9555: .seealso: MatMatMult(), MatMatMultNumeric()
9556: @*/
9557: PetscErrorCode MatMatMultSymbolic(Mat A,Mat B,PetscReal fill,Mat *C)
9558: {
9560: PetscErrorCode (*Asymbolic)(Mat,Mat,PetscReal,Mat*);
9561: PetscErrorCode (*Bsymbolic)(Mat,Mat,PetscReal,Mat*);
9562: PetscErrorCode (*symbolic)(Mat,Mat,PetscReal,Mat*)=NULL;
9567: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9568: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9572: MatCheckPreallocated(B,2);
9573: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9574: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9577: 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);
9578: if (fill == PETSC_DEFAULT) fill = 2.0;
9579: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9580: MatCheckPreallocated(A,1);
9582: Asymbolic = A->ops->matmultsymbolic;
9583: Bsymbolic = B->ops->matmultsymbolic;
9584: if (Asymbolic == Bsymbolic) {
9585: if (!Bsymbolic) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"C=A*B not implemented for B of type %s",((PetscObject)B)->type_name);
9586: symbolic = Bsymbolic;
9587: } else { /* dispatch based on the type of A and B */
9588: char symbolicname[256];
9589: PetscStrcpy(symbolicname,"MatMatMultSymbolic_");
9590: PetscStrcat(symbolicname,((PetscObject)A)->type_name);
9591: PetscStrcat(symbolicname,"_");
9592: PetscStrcat(symbolicname,((PetscObject)B)->type_name);
9593: PetscStrcat(symbolicname,"_C");
9594: PetscObjectQueryFunction((PetscObject)B,symbolicname,&symbolic);
9595: 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);
9596: }
9597: PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);
9598: (*symbolic)(A,B,fill,C);
9599: PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);
9600: return(0);
9601: }
9605: /*@
9606: MatMatMultNumeric - Performs the numeric matrix-matrix product.
9607: Call this routine after first calling MatMatMultSymbolic().
9609: Neighbor-wise Collective on Mat
9611: Input Parameters:
9612: + A - the left matrix
9613: - B - the right matrix
9615: Output Parameters:
9616: . C - the product matrix, which was created by from MatMatMultSymbolic() or a call to MatMatMult().
9618: Notes:
9619: C must have been created with MatMatMultSymbolic().
9621: This routine is currently implemented for
9622: - pairs of AIJ matrices and classes which inherit from AIJ, C will be of type MATAIJ.
9623: - pairs of AIJ (A) and Dense (B) matrix, C will be of type Dense.
9624: - pairs of Dense (A) and AIJ (B) matrix, C will be of type Dense.
9626: Level: intermediate
9628: .seealso: MatMatMult(), MatMatMultSymbolic()
9629: @*/
9630: PetscErrorCode MatMatMultNumeric(Mat A,Mat B,Mat C)
9631: {
9635: MatMatMult(A,B,MAT_REUSE_MATRIX,0.0,&C);
9636: return(0);
9637: }
9641: /*@
9642: MatMatTransposeMult - Performs Matrix-Matrix Multiplication C=A*B^T.
9644: Neighbor-wise Collective on Mat
9646: Input Parameters:
9647: + A - the left matrix
9648: . B - the right matrix
9649: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9650: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9652: Output Parameters:
9653: . C - the product matrix
9655: Notes:
9656: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9658: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9660: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9661: actually needed.
9663: This routine is currently only implemented for pairs of SeqAIJ matrices. C will be of type MATSEQAIJ.
9665: Level: intermediate
9667: .seealso: MatMatTransposeMultSymbolic(), MatMatTransposeMultNumeric(), MatMatMult(), MatTransposeMatMult() MatPtAP()
9668: @*/
9669: PetscErrorCode MatMatTransposeMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9670: {
9672: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9673: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9678: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9679: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9682: MatCheckPreallocated(B,2);
9683: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9684: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9686: 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);
9687: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9688: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9689: MatCheckPreallocated(A,1);
9691: fA = A->ops->mattransposemult;
9692: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);
9693: fB = B->ops->mattransposemult;
9694: if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);
9695: 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);
9697: PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);
9698: if (scall == MAT_INITIAL_MATRIX) {
9699: PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);
9700: (*A->ops->mattransposemultsymbolic)(A,B,fill,C);
9701: PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);
9702: }
9703: PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);
9704: (*A->ops->mattransposemultnumeric)(A,B,*C);
9705: PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);
9706: PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);
9707: return(0);
9708: }
9712: /*@
9713: MatTransposeMatMult - Performs Matrix-Matrix Multiplication C=A^T*B.
9715: Neighbor-wise Collective on Mat
9717: Input Parameters:
9718: + A - the left matrix
9719: . B - the right matrix
9720: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9721: - fill - expected fill as ratio of nnz(C)/(nnz(A) + nnz(B)), use PETSC_DEFAULT if not known
9723: Output Parameters:
9724: . C - the product matrix
9726: Notes:
9727: C will be created if MAT_INITIAL_MATRIX and must be destroyed by the user with MatDestroy().
9729: MAT_REUSE_MATRIX can only be used if the matrices A and B have the same nonzero pattern as in the previous call
9731: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9732: actually needed.
9734: This routine is currently implemented for pairs of AIJ matrices and pairs of SeqDense matrices and classes
9735: which inherit from SeqAIJ. C will be of same type as the input matrices.
9737: Level: intermediate
9739: .seealso: MatTransposeMatMultSymbolic(), MatTransposeMatMultNumeric(), MatMatMult(), MatMatTransposeMult(), MatPtAP()
9740: @*/
9741: PetscErrorCode MatTransposeMatMult(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
9742: {
9744: PetscErrorCode (*fA)(Mat,Mat,MatReuse,PetscReal,Mat*);
9745: PetscErrorCode (*fB)(Mat,Mat,MatReuse,PetscReal,Mat*);
9746: PetscErrorCode (*transposematmult)(Mat,Mat,MatReuse,PetscReal,Mat*) = NULL;
9751: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9752: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9755: MatCheckPreallocated(B,2);
9756: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9757: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9759: 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);
9760: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9761: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be > 1.0",(double)fill);
9762: MatCheckPreallocated(A,1);
9764: fA = A->ops->transposematmult;
9765: fB = B->ops->transposematmult;
9766: if (fB==fA) {
9767: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9768: transposematmult = fA;
9769: } else {
9770: /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */
9771: char multname[256];
9772: PetscStrcpy(multname,"MatTransposeMatMult_");
9773: PetscStrcat(multname,((PetscObject)A)->type_name);
9774: PetscStrcat(multname,"_");
9775: PetscStrcat(multname,((PetscObject)B)->type_name);
9776: PetscStrcat(multname,"_C"); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */
9777: PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);
9778: 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);
9779: }
9780: PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);
9781: (*transposematmult)(A,B,scall,fill,C);
9782: PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);
9783: return(0);
9784: }
9788: /*@
9789: MatMatMatMult - Performs Matrix-Matrix-Matrix Multiplication D=A*B*C.
9791: Neighbor-wise Collective on Mat
9793: Input Parameters:
9794: + A - the left matrix
9795: . B - the middle matrix
9796: . C - the right matrix
9797: . scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9798: - 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
9799: if the result is a dense matrix this is irrelevent
9801: Output Parameters:
9802: . D - the product matrix
9804: Notes:
9805: Unless scall is MAT_REUSE_MATRIX D will be created.
9807: MAT_REUSE_MATRIX can only be used if the matrices A, B and C have the same nonzero pattern as in the previous call
9809: To determine the correct fill value, run with -info and search for the string "Fill ratio" to see the value
9810: actually needed.
9812: If you have many matrices with the same non-zero structure to multiply, you
9813: should use MAT_REUSE_MATRIX in all calls but the first or
9815: Level: intermediate
9817: .seealso: MatMatMult, MatPtAP()
9818: @*/
9819: PetscErrorCode MatMatMatMult(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
9820: {
9822: PetscErrorCode (*fA)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9823: PetscErrorCode (*fB)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9824: PetscErrorCode (*fC)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*);
9825: PetscErrorCode (*mult)(Mat,Mat,Mat,MatReuse,PetscReal,Mat*)=NULL;
9830: MatCheckPreallocated(A,1);
9831: if (!A->assembled) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9832: if (A->factortype) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9835: MatCheckPreallocated(B,2);
9836: if (!B->assembled) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9837: if (B->factortype) SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9840: MatCheckPreallocated(C,3);
9841: if (!C->assembled) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9842: if (C->factortype) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9843: 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);
9844: 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);
9845: if (scall == MAT_REUSE_MATRIX) {
9848: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9849: (*(*D)->ops->matmatmult)(A,B,C,scall,fill,D);
9850: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9851: return(0);
9852: }
9853: if (fill == PETSC_DEFAULT || fill == PETSC_DECIDE) fill = 2.0;
9854: if (fill < 1.0) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_SIZ,"Expected fill=%g must be >= 1.0",(double)fill);
9856: fA = A->ops->matmatmult;
9857: fB = B->ops->matmatmult;
9858: fC = C->ops->matmatmult;
9859: if (fA == fB && fA == fC) {
9860: if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatMatMult not supported for A of type %s",((PetscObject)A)->type_name);
9861: mult = fA;
9862: } else {
9863: /* dispatch based on the type of A, B and C from their PetscObject's PetscFunctionLists. */
9864: char multname[256];
9865: PetscStrcpy(multname,"MatMatMatMult_");
9866: PetscStrcat(multname,((PetscObject)A)->type_name);
9867: PetscStrcat(multname,"_");
9868: PetscStrcat(multname,((PetscObject)B)->type_name);
9869: PetscStrcat(multname,"_");
9870: PetscStrcat(multname,((PetscObject)C)->type_name);
9871: PetscStrcat(multname,"_C");
9872: PetscObjectQueryFunction((PetscObject)B,multname,&mult);
9873: 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);
9874: }
9875: PetscLogEventBegin(MAT_MatMatMult,A,B,0,0);
9876: (*mult)(A,B,C,scall,fill,D);
9877: PetscLogEventEnd(MAT_MatMatMult,A,B,0,0);
9878: return(0);
9879: }
9883: /*@
9884: MatCreateRedundantMatrix - Create redundant matrices and put them into processors of subcommunicators.
9886: Collective on Mat
9888: Input Parameters:
9889: + mat - the matrix
9890: . nsubcomm - the number of subcommunicators (= number of redundant parallel or sequential matrices)
9891: . subcomm - MPI communicator split from the communicator where mat resides in (or MPI_COMM_NULL if nsubcomm is used)
9892: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
9894: Output Parameter:
9895: . matredundant - redundant matrix
9897: Notes:
9898: MAT_REUSE_MATRIX can only be used when the nonzero structure of the
9899: original matrix has not changed from that last call to MatCreateRedundantMatrix().
9901: This routine creates the duplicated matrices in subcommunicators; you should NOT create them before
9902: calling it.
9904: Level: advanced
9906: Concepts: subcommunicator
9907: Concepts: duplicate matrix
9909: .seealso: MatDestroy()
9910: @*/
9911: PetscErrorCode MatCreateRedundantMatrix(Mat mat,PetscInt nsubcomm,MPI_Comm subcomm,MatReuse reuse,Mat *matredundant)
9912: {
9914: MPI_Comm comm;
9915: PetscMPIInt size;
9916: PetscInt mloc_sub,rstart,rend,M=mat->rmap->N,N=mat->cmap->N,bs=mat->rmap->bs;
9917: Mat_Redundant *redund=NULL;
9918: PetscSubcomm psubcomm=NULL;
9919: MPI_Comm subcomm_in=subcomm;
9920: Mat *matseq;
9921: IS isrow,iscol;
9922: PetscBool newsubcomm=PETSC_FALSE;
9925: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
9926: if (size == 1 || nsubcomm == 1) {
9927: if (reuse == MAT_INITIAL_MATRIX) {
9928: MatDuplicate(mat,MAT_COPY_VALUES,matredundant);
9929: } else {
9930: MatCopy(mat,*matredundant,SAME_NONZERO_PATTERN);
9931: }
9932: return(0);
9933: }
9936: if (nsubcomm && reuse == MAT_REUSE_MATRIX) {
9939: }
9940: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
9941: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
9942: MatCheckPreallocated(mat,1);
9944: PetscLogEventBegin(MAT_RedundantMat,mat,0,0,0);
9945: if (subcomm_in == MPI_COMM_NULL && reuse == MAT_INITIAL_MATRIX) { /* get subcomm if user does not provide subcomm */
9946: /* create psubcomm, then get subcomm */
9947: PetscObjectGetComm((PetscObject)mat,&comm);
9948: MPI_Comm_size(comm,&size);
9949: if (nsubcomm < 1 || nsubcomm > size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"nsubcomm must between 1 and %D",size);
9951: PetscSubcommCreate(comm,&psubcomm);
9952: PetscSubcommSetNumber(psubcomm,nsubcomm);
9953: PetscSubcommSetType(psubcomm,PETSC_SUBCOMM_CONTIGUOUS);
9954: PetscSubcommSetFromOptions(psubcomm);
9955: PetscCommDuplicate(PetscSubcommChild(psubcomm),&subcomm,NULL);
9956: newsubcomm = PETSC_TRUE;
9957: PetscSubcommDestroy(&psubcomm);
9958: }
9960: /* get isrow, iscol and a local sequential matrix matseq[0] */
9961: if (reuse == MAT_INITIAL_MATRIX) {
9962: mloc_sub = PETSC_DECIDE;
9963: if (bs < 1) {
9964: PetscSplitOwnership(subcomm,&mloc_sub,&M);
9965: } else {
9966: PetscSplitOwnershipBlock(subcomm,bs,&mloc_sub,&M);
9967: }
9968: MPI_Scan(&mloc_sub,&rend,1,MPIU_INT,MPI_SUM,subcomm);
9969: rstart = rend - mloc_sub;
9970: ISCreateStride(PETSC_COMM_SELF,mloc_sub,rstart,1,&isrow);
9971: ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
9972: } else { /* reuse == MAT_REUSE_MATRIX */
9973: /* retrieve subcomm */
9974: PetscObjectGetComm((PetscObject)(*matredundant),&subcomm);
9975: redund = (*matredundant)->redundant;
9976: isrow = redund->isrow;
9977: iscol = redund->iscol;
9978: matseq = redund->matseq;
9979: }
9980: MatGetSubMatrices(mat,1,&isrow,&iscol,reuse,&matseq);
9982: /* get matredundant over subcomm */
9983: if (reuse == MAT_INITIAL_MATRIX) {
9984: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],mloc_sub,reuse,matredundant);
9986: /* create a supporting struct and attach it to C for reuse */
9987: PetscNewLog(*matredundant,&redund);
9988: (*matredundant)->redundant = redund;
9989: redund->isrow = isrow;
9990: redund->iscol = iscol;
9991: redund->matseq = matseq;
9992: if (newsubcomm) {
9993: redund->subcomm = subcomm;
9994: } else {
9995: redund->subcomm = MPI_COMM_NULL;
9996: }
9997: } else {
9998: MatCreateMPIMatConcatenateSeqMat(subcomm,matseq[0],PETSC_DECIDE,reuse,matredundant);
9999: }
10000: PetscLogEventEnd(MAT_RedundantMat,mat,0,0,0);
10001: return(0);
10002: }
10006: /*@C
10007: MatGetMultiProcBlock - Create multiple [bjacobi] 'parallel submatrices' from
10008: a given 'mat' object. Each submatrix can span multiple procs.
10010: Collective on Mat
10012: Input Parameters:
10013: + mat - the matrix
10014: . subcomm - the subcommunicator obtained by com_split(comm)
10015: - scall - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10017: Output Parameter:
10018: . subMat - 'parallel submatrices each spans a given subcomm
10020: Notes:
10021: The submatrix partition across processors is dictated by 'subComm' a
10022: communicator obtained by com_split(comm). The comm_split
10023: is not restriced to be grouped with consecutive original ranks.
10025: Due the comm_split() usage, the parallel layout of the submatrices
10026: map directly to the layout of the original matrix [wrt the local
10027: row,col partitioning]. So the original 'DiagonalMat' naturally maps
10028: into the 'DiagonalMat' of the subMat, hence it is used directly from
10029: the subMat. However the offDiagMat looses some columns - and this is
10030: reconstructed with MatSetValues()
10032: Level: advanced
10034: Concepts: subcommunicator
10035: Concepts: submatrices
10037: .seealso: MatGetSubMatrices()
10038: @*/
10039: PetscErrorCode MatGetMultiProcBlock(Mat mat, MPI_Comm subComm, MatReuse scall,Mat *subMat)
10040: {
10042: PetscMPIInt commsize,subCommSize;
10045: MPI_Comm_size(PetscObjectComm((PetscObject)mat),&commsize);
10046: MPI_Comm_size(subComm,&subCommSize);
10047: if (subCommSize > commsize) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_OUTOFRANGE,"CommSize %D < SubCommZize %D",commsize,subCommSize);
10049: PetscLogEventBegin(MAT_GetMultiProcBlock,mat,0,0,0);
10050: (*mat->ops->getmultiprocblock)(mat,subComm,scall,subMat);
10051: PetscLogEventEnd(MAT_GetMultiProcBlock,mat,0,0,0);
10052: return(0);
10053: }
10057: /*@
10058: MatGetLocalSubMatrix - Gets a reference to a submatrix specified in local numbering
10060: Not Collective
10062: Input Arguments:
10063: mat - matrix to extract local submatrix from
10064: isrow - local row indices for submatrix
10065: iscol - local column indices for submatrix
10067: Output Arguments:
10068: submat - the submatrix
10070: Level: intermediate
10072: Notes:
10073: The submat should be returned with MatRestoreLocalSubMatrix().
10075: Depending on the format of mat, the returned submat may not implement MatMult(). Its communicator may be
10076: the same as mat, it may be PETSC_COMM_SELF, or some other subcomm of mat's.
10078: The submat always implements MatSetValuesLocal(). If isrow and iscol have the same block size, then
10079: MatSetValuesBlockedLocal() will also be implemented.
10081: The mat must have had a ISLocalToGlobalMapping provided to it with MatSetLocalToGlobalMapping(). Note that
10082: matrices obtained with DMCreateMat() generally already have the local to global mapping provided.
10084: .seealso: MatRestoreLocalSubMatrix(), MatCreateLocalRef(), MatSetLocalToGlobalMapping()
10085: @*/
10086: PetscErrorCode MatGetLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10087: {
10096: if (!mat->rmap->mapping) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Matrix must have local to global mapping provided before this call");
10097:
10098: if (mat->ops->getlocalsubmatrix) {
10099: (*mat->ops->getlocalsubmatrix)(mat,isrow,iscol,submat);
10100: } else {
10101: MatCreateLocalRef(mat,isrow,iscol,submat);
10102: }
10103: return(0);
10104: }
10108: /*@
10109: MatRestoreLocalSubMatrix - Restores a reference to a submatrix specified in local numbering
10111: Not Collective
10113: Input Arguments:
10114: mat - matrix to extract local submatrix from
10115: isrow - local row indices for submatrix
10116: iscol - local column indices for submatrix
10117: submat - the submatrix
10119: Level: intermediate
10121: .seealso: MatGetLocalSubMatrix()
10122: @*/
10123: PetscErrorCode MatRestoreLocalSubMatrix(Mat mat,IS isrow,IS iscol,Mat *submat)
10124: {
10133: if (*submat) {
10135: }
10137: if (mat->ops->restorelocalsubmatrix) {
10138: (*mat->ops->restorelocalsubmatrix)(mat,isrow,iscol,submat);
10139: } else {
10140: MatDestroy(submat);
10141: }
10142: *submat = NULL;
10143: return(0);
10144: }
10146: /* --------------------------------------------------------*/
10149: /*@
10150: MatFindZeroDiagonals - Finds all the rows of a matrix that have zero or no entry in the matrix
10152: Collective on Mat
10154: Input Parameter:
10155: . mat - the matrix
10157: Output Parameter:
10158: . is - if any rows have zero diagonals this contains the list of them
10160: Level: developer
10162: Concepts: matrix-vector product
10164: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10165: @*/
10166: PetscErrorCode MatFindZeroDiagonals(Mat mat,IS *is)
10167: {
10173: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10174: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10176: if (!mat->ops->findzerodiagonals) {
10177: Vec diag;
10178: const PetscScalar *a;
10179: PetscInt *rows;
10180: PetscInt rStart, rEnd, r, nrow = 0;
10182: MatCreateVecs(mat, &diag, NULL);
10183: MatGetDiagonal(mat, diag);
10184: MatGetOwnershipRange(mat, &rStart, &rEnd);
10185: VecGetArrayRead(diag, &a);
10186: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) ++nrow;
10187: PetscMalloc1(nrow, &rows);
10188: nrow = 0;
10189: for (r = 0; r < rEnd-rStart; ++r) if (a[r] == 0.0) rows[nrow++] = r+rStart;
10190: VecRestoreArrayRead(diag, &a);
10191: VecDestroy(&diag);
10192: ISCreateGeneral(PetscObjectComm((PetscObject) mat), nrow, rows, PETSC_OWN_POINTER, is);
10193: } else {
10194: (*mat->ops->findzerodiagonals)(mat, is);
10195: }
10196: return(0);
10197: }
10201: /*@
10202: MatFindOffBlockDiagonalEntries - Finds all the rows of a matrix that have entries outside of the main diagonal block (defined by the matrix block size)
10204: Collective on Mat
10206: Input Parameter:
10207: . mat - the matrix
10209: Output Parameter:
10210: . is - contains the list of rows with off block diagonal entries
10212: Level: developer
10214: Concepts: matrix-vector product
10216: .seealso: MatMultTranspose(), MatMultAdd(), MatMultTransposeAdd()
10217: @*/
10218: PetscErrorCode MatFindOffBlockDiagonalEntries(Mat mat,IS *is)
10219: {
10225: if (!mat->assembled) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10226: if (mat->factortype) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10228: if (!mat->ops->findoffblockdiagonalentries) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"This matrix type does not have a find off block diagonal entries defined");
10229: (*mat->ops->findoffblockdiagonalentries)(mat,is);
10230: return(0);
10231: }
10235: /*@C
10236: MatInvertBlockDiagonal - Inverts the block diagonal entries.
10238: Collective on Mat
10240: Input Parameters:
10241: . mat - the matrix
10243: Output Parameters:
10244: . values - the block inverses in column major order (FORTRAN-like)
10246: Note:
10247: This routine is not available from Fortran.
10249: Level: advanced
10250: @*/
10251: PetscErrorCode MatInvertBlockDiagonal(Mat mat,const PetscScalar **values)
10252: {
10257: if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for unassembled matrix");
10258: if (mat->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
10259: if (!mat->ops->invertblockdiagonal) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported");
10260: (*mat->ops->invertblockdiagonal)(mat,values);
10261: return(0);
10262: }
10266: /*@C
10267: MatTransposeColoringDestroy - Destroys a coloring context for matrix product C=A*B^T that was created
10268: via MatTransposeColoringCreate().
10270: Collective on MatTransposeColoring
10272: Input Parameter:
10273: . c - coloring context
10275: Level: intermediate
10277: .seealso: MatTransposeColoringCreate()
10278: @*/
10279: PetscErrorCode MatTransposeColoringDestroy(MatTransposeColoring *c)
10280: {
10281: PetscErrorCode ierr;
10282: MatTransposeColoring matcolor=*c;
10285: if (!matcolor) return(0);
10286: if (--((PetscObject)matcolor)->refct > 0) {matcolor = 0; return(0);}
10288: PetscFree3(matcolor->ncolumns,matcolor->nrows,matcolor->colorforrow);
10289: PetscFree(matcolor->rows);
10290: PetscFree(matcolor->den2sp);
10291: PetscFree(matcolor->colorforcol);
10292: PetscFree(matcolor->columns);
10293: if (matcolor->brows>0) {
10294: PetscFree(matcolor->lstart);
10295: }
10296: PetscHeaderDestroy(c);
10297: return(0);
10298: }
10302: /*@C
10303: MatTransColoringApplySpToDen - Given a symbolic matrix product C=A*B^T for which
10304: a MatTransposeColoring context has been created, computes a dense B^T by Apply
10305: MatTransposeColoring to sparse B.
10307: Collective on MatTransposeColoring
10309: Input Parameters:
10310: + B - sparse matrix B
10311: . Btdense - symbolic dense matrix B^T
10312: - coloring - coloring context created with MatTransposeColoringCreate()
10314: Output Parameter:
10315: . Btdense - dense matrix B^T
10317: Options Database Keys:
10318: + -mat_transpose_coloring_view - Activates basic viewing or coloring
10319: . -mat_transpose_coloring_view_draw - Activates drawing of coloring
10320: - -mat_transpose_coloring_view_info - Activates viewing of coloring info
10322: Level: intermediate
10324: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy()
10326: .keywords: coloring
10327: @*/
10328: PetscErrorCode MatTransColoringApplySpToDen(MatTransposeColoring coloring,Mat B,Mat Btdense)
10329: {
10337: if (!B->ops->transcoloringapplysptoden) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)B)->type_name);
10338: (B->ops->transcoloringapplysptoden)(coloring,B,Btdense);
10339: return(0);
10340: }
10344: /*@C
10345: MatTransColoringApplyDenToSp - Given a symbolic matrix product Csp=A*B^T for which
10346: a MatTransposeColoring context has been created and a dense matrix Cden=A*Btdense
10347: in which Btdens is obtained from MatTransColoringApplySpToDen(), recover sparse matrix
10348: Csp from Cden.
10350: Collective on MatTransposeColoring
10352: Input Parameters:
10353: + coloring - coloring context created with MatTransposeColoringCreate()
10354: - Cden - matrix product of a sparse matrix and a dense matrix Btdense
10356: Output Parameter:
10357: . Csp - sparse matrix
10359: Options Database Keys:
10360: + -mat_multtranspose_coloring_view - Activates basic viewing or coloring
10361: . -mat_multtranspose_coloring_view_draw - Activates drawing of coloring
10362: - -mat_multtranspose_coloring_view_info - Activates viewing of coloring info
10364: Level: intermediate
10366: .seealso: MatTransposeColoringCreate(), MatTransposeColoringDestroy(), MatTransColoringApplySpToDen()
10368: .keywords: coloring
10369: @*/
10370: PetscErrorCode MatTransColoringApplyDenToSp(MatTransposeColoring matcoloring,Mat Cden,Mat Csp)
10371: {
10379: if (!Csp->ops->transcoloringapplydentosp) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not supported for this matrix type %s",((PetscObject)Csp)->type_name);
10380: (Csp->ops->transcoloringapplydentosp)(matcoloring,Cden,Csp);
10381: return(0);
10382: }
10386: /*@C
10387: MatTransposeColoringCreate - Creates a matrix coloring context for matrix product C=A*B^T.
10389: Collective on Mat
10391: Input Parameters:
10392: + mat - the matrix product C
10393: - iscoloring - the coloring of the matrix; usually obtained with MatColoringCreate() or DMCreateColoring()
10395: Output Parameter:
10396: . color - the new coloring context
10398: Level: intermediate
10400: .seealso: MatTransposeColoringDestroy(), MatTransposeColoringSetFromOptions(), MatTransColoringApplySpToDen(),
10401: MatTransColoringApplyDenToSp(), MatTransposeColoringView(),
10402: @*/
10403: PetscErrorCode MatTransposeColoringCreate(Mat mat,ISColoring iscoloring,MatTransposeColoring *color)
10404: {
10405: MatTransposeColoring c;
10406: MPI_Comm comm;
10407: PetscErrorCode ierr;
10410: PetscLogEventBegin(MAT_TransposeColoringCreate,mat,0,0,0);
10411: PetscObjectGetComm((PetscObject)mat,&comm);
10412: PetscHeaderCreate(c,MAT_TRANSPOSECOLORING_CLASSID,"MatTransposeColoring","Matrix product C=A*B^T via coloring","Mat",comm,MatTransposeColoringDestroy,NULL);
10414: c->ctype = iscoloring->ctype;
10415: if (mat->ops->transposecoloringcreate) {
10416: (*mat->ops->transposecoloringcreate)(mat,iscoloring,c);
10417: } else SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Code not yet written for this matrix type");
10419: *color = c;
10420: PetscLogEventEnd(MAT_TransposeColoringCreate,mat,0,0,0);
10421: return(0);
10422: }
10426: /*@
10427: MatGetNonzeroState - Returns a 64 bit integer representing the current state of nonzeros in the matrix. If the
10428: matrix has had no new nonzero locations added to the matrix since the previous call then the value will be the
10429: same, otherwise it will be larger
10431: Not Collective
10433: Input Parameter:
10434: . A - the matrix
10436: Output Parameter:
10437: . state - the current state
10439: Notes: You can only compare states from two different calls to the SAME matrix, you cannot compare calls between
10440: different matrices
10442: Level: intermediate
10444: @*/
10445: PetscErrorCode MatGetNonzeroState(Mat mat,PetscObjectState *state)
10446: {
10449: *state = mat->nonzerostate;
10450: return(0);
10451: }
10455: /*@
10456: MatCreateMPIMatConcatenateSeqMat - Creates a single large PETSc matrix by concatenating sequential
10457: matrices from each processor
10459: Collective on MPI_Comm
10461: Input Parameters:
10462: + comm - the communicators the parallel matrix will live on
10463: . seqmat - the input sequential matrices
10464: . n - number of local columns (or PETSC_DECIDE)
10465: - reuse - either MAT_INITIAL_MATRIX or MAT_REUSE_MATRIX
10467: Output Parameter:
10468: . mpimat - the parallel matrix generated
10470: Level: advanced
10472: Notes: The number of columns of the matrix in EACH processor MUST be the same.
10474: @*/
10475: PetscErrorCode MatCreateMPIMatConcatenateSeqMat(MPI_Comm comm,Mat seqmat,PetscInt n,MatReuse reuse,Mat *mpimat)
10476: {
10478: PetscMPIInt size;
10481: MPI_Comm_size(comm,&size);
10482: if (size == 1) {
10483: if (reuse == MAT_INITIAL_MATRIX) {
10484: MatDuplicate(seqmat,MAT_COPY_VALUES,mpimat);
10485: } else {
10486: MatCopy(seqmat,*mpimat,SAME_NONZERO_PATTERN);
10487: }
10488: return(0);
10489: }
10491: if (!seqmat->ops->creatempimatconcatenateseqmat) SETERRQ1(PetscObjectComm((PetscObject)seqmat),PETSC_ERR_SUP,"Mat type %s",((PetscObject)seqmat)->type_name);
10492: PetscLogEventBegin(MAT_Merge,seqmat,0,0,0);
10493: (*seqmat->ops->creatempimatconcatenateseqmat)(comm,seqmat,n,reuse,mpimat);
10494: PetscLogEventEnd(MAT_Merge,seqmat,0,0,0);
10495: return(0);
10496: }
10500: /*@
10501: MatSubdomainsCreateCoalesce - Creates index subdomains by coalescing adjacent
10502: ranks' ownership ranges.
10504: Collective on A
10506: Input Parameters:
10507: + A - the matrix to create subdomains from
10508: - N - requested number of subdomains
10511: Output Parameters:
10512: + n - number of subdomains resulting on this rank
10513: - iss - IS list with indices of subdomains on this rank
10515: Level: advanced
10517: Notes: number of subdomains must be smaller than the communicator size
10518: @*/
10519: PetscErrorCode MatSubdomainsCreateCoalesce(Mat A,PetscInt N,PetscInt *n,IS *iss[])
10520: {
10521: MPI_Comm comm,subcomm;
10522: PetscMPIInt size,rank,color;
10523: PetscInt rstart,rend,k;
10524: PetscErrorCode ierr;
10527: PetscObjectGetComm((PetscObject)A,&comm);
10528: MPI_Comm_size(comm,&size);
10529: MPI_Comm_rank(comm,&rank);
10530: 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);
10531: *n = 1;
10532: k = ((PetscInt)size)/N + ((PetscInt)size%N>0); /* There are up to k ranks to a color */
10533: color = rank/k;
10534: MPI_Comm_split(comm,color,rank,&subcomm);
10535: PetscMalloc1(1,iss);
10536: MatGetOwnershipRange(A,&rstart,&rend);
10537: ISCreateStride(subcomm,rend-rstart,rstart,1,iss[0]);
10538: MPI_Comm_free(&subcomm);
10539: return(0);
10540: }