xref: /petsc/src/mat/impls/scatter/mscatter.c (revision 0700a8246d308f50502909ba325e6169d3ee27eb)
12a6744ebSBarry Smith #define PETSCMAT_DLL
22a6744ebSBarry Smith 
32a6744ebSBarry Smith /*
42a6744ebSBarry Smith    This provides a matrix that applies a VecScatter to a vector.
52a6744ebSBarry Smith */
62a6744ebSBarry Smith 
77c4f633dSBarry Smith #include "private/matimpl.h"        /*I "petscmat.h" I*/
82a6744ebSBarry Smith #include "private/vecimpl.h"
92a6744ebSBarry Smith 
102a6744ebSBarry Smith typedef struct {
112a6744ebSBarry Smith   VecScatter scatter;
122a6744ebSBarry Smith } Mat_Scatter;
132a6744ebSBarry Smith 
142a6744ebSBarry Smith #undef __FUNCT__
152a6744ebSBarry Smith #define __FUNCT__ "MatScatterGetVecScatter"
162a6744ebSBarry Smith /*@
172a6744ebSBarry Smith     MatScatterGetVecScatter - Returns the user-provided scatter set with MatScatterSetVecScatter()
182a6744ebSBarry Smith 
192a6744ebSBarry Smith     Not Collective, but not cannot use scatter if not used collectively on Mat
202a6744ebSBarry Smith 
212a6744ebSBarry Smith     Input Parameter:
222a6744ebSBarry Smith .   mat - the matrix, should have been created with MatCreateScatter() or have type MATSCATTER
232a6744ebSBarry Smith 
242a6744ebSBarry Smith     Output Parameter:
252a6744ebSBarry Smith .   scatter - the scatter context
262a6744ebSBarry Smith 
272a6744ebSBarry Smith     Level: intermediate
282a6744ebSBarry Smith 
292a6744ebSBarry Smith .keywords: matrix, scatter, get
302a6744ebSBarry Smith 
312a6744ebSBarry Smith .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER
322a6744ebSBarry Smith @*/
332a6744ebSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatScatterGetVecScatter(Mat mat,VecScatter *scatter)
342a6744ebSBarry Smith {
352a6744ebSBarry Smith   Mat_Scatter    *mscatter;
362a6744ebSBarry Smith 
372a6744ebSBarry Smith   PetscFunctionBegin;
38*0700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
392a6744ebSBarry Smith   PetscValidPointer(scatter,2);
402a6744ebSBarry Smith   mscatter = (Mat_Scatter*)mat->data;
412a6744ebSBarry Smith   *scatter = mscatter->scatter;
422a6744ebSBarry Smith   PetscFunctionReturn(0);
432a6744ebSBarry Smith }
442a6744ebSBarry Smith 
452a6744ebSBarry Smith #undef __FUNCT__
462a6744ebSBarry Smith #define __FUNCT__ "MatDestroy_Scatter"
472a6744ebSBarry Smith PetscErrorCode MatDestroy_Scatter(Mat mat)
482a6744ebSBarry Smith {
492a6744ebSBarry Smith   PetscErrorCode ierr;
502a6744ebSBarry Smith   Mat_Scatter    *scatter = (Mat_Scatter*)mat->data;
512a6744ebSBarry Smith 
522a6744ebSBarry Smith   PetscFunctionBegin;
532a6744ebSBarry Smith   if (scatter->scatter) {ierr = VecScatterDestroy(scatter->scatter);CHKERRQ(ierr);}
542a6744ebSBarry Smith   ierr = PetscFree(scatter);CHKERRQ(ierr);
552a6744ebSBarry Smith   PetscFunctionReturn(0);
562a6744ebSBarry Smith }
572a6744ebSBarry Smith 
582a6744ebSBarry Smith #undef __FUNCT__
592a6744ebSBarry Smith #define __FUNCT__ "MatMult_Scatter"
602a6744ebSBarry Smith PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y)
612a6744ebSBarry Smith {
622a6744ebSBarry Smith   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;
632a6744ebSBarry Smith   PetscErrorCode ierr;
642a6744ebSBarry Smith 
652a6744ebSBarry Smith   PetscFunctionBegin;
662a6744ebSBarry Smith   if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
6774d95942SJed Brown   ierr = VecZeroEntries(y);CHKERRQ(ierr);
6874d95942SJed Brown   ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
6974d95942SJed Brown   ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
702a6744ebSBarry Smith   PetscFunctionReturn(0);
712a6744ebSBarry Smith }
722a6744ebSBarry Smith 
732a6744ebSBarry Smith #undef __FUNCT__
742a6744ebSBarry Smith #define __FUNCT__ "MatMultAdd_Scatter"
752a6744ebSBarry Smith PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
762a6744ebSBarry Smith {
772a6744ebSBarry Smith   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;
782a6744ebSBarry Smith   PetscErrorCode ierr;
792a6744ebSBarry Smith 
802a6744ebSBarry Smith   PetscFunctionBegin;
812a6744ebSBarry Smith   if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
822a6744ebSBarry Smith   if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);}
83ca9f406cSSatish Balay   ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
84ca9f406cSSatish Balay   ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
852a6744ebSBarry Smith   PetscFunctionReturn(0);
862a6744ebSBarry Smith }
872a6744ebSBarry Smith 
882a6744ebSBarry Smith #undef __FUNCT__
892a6744ebSBarry Smith #define __FUNCT__ "MatMultTranspose_Scatter"
902a6744ebSBarry Smith PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y)
912a6744ebSBarry Smith {
922a6744ebSBarry Smith   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;
932a6744ebSBarry Smith   PetscErrorCode ierr;
942a6744ebSBarry Smith 
952a6744ebSBarry Smith   PetscFunctionBegin;
962a6744ebSBarry Smith   if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
9774d95942SJed Brown   ierr = VecZeroEntries(y);CHKERRQ(ierr);
9874d95942SJed Brown   ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
9974d95942SJed Brown   ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1002a6744ebSBarry Smith   PetscFunctionReturn(0);
1012a6744ebSBarry Smith }
1022a6744ebSBarry Smith 
1032a6744ebSBarry Smith #undef __FUNCT__
1042a6744ebSBarry Smith #define __FUNCT__ "MatMultTransposeAdd_Scatter"
1052a6744ebSBarry Smith PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
1062a6744ebSBarry Smith {
1072a6744ebSBarry Smith   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;
1082a6744ebSBarry Smith   PetscErrorCode ierr;
1092a6744ebSBarry Smith 
1102a6744ebSBarry Smith   PetscFunctionBegin;
1112a6744ebSBarry Smith   if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
1122a6744ebSBarry Smith   if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);}
113ca9f406cSSatish Balay   ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
114ca9f406cSSatish Balay   ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
1152a6744ebSBarry Smith   PetscFunctionReturn(0);
1162a6744ebSBarry Smith }
1172a6744ebSBarry Smith 
1182a6744ebSBarry Smith static struct _MatOps MatOps_Values = {0,
1192a6744ebSBarry Smith        0,
1202a6744ebSBarry Smith        0,
1212a6744ebSBarry Smith        MatMult_Scatter,
1222a6744ebSBarry Smith /* 4*/ MatMultAdd_Scatter,
1232a6744ebSBarry Smith        MatMultTranspose_Scatter,
1242a6744ebSBarry Smith        MatMultTransposeAdd_Scatter,
1252a6744ebSBarry Smith        0,
1262a6744ebSBarry Smith        0,
1272a6744ebSBarry Smith        0,
1282a6744ebSBarry Smith /*10*/ 0,
1292a6744ebSBarry Smith        0,
1302a6744ebSBarry Smith        0,
1312a6744ebSBarry Smith        0,
1322a6744ebSBarry Smith        0,
1332a6744ebSBarry Smith /*15*/ 0,
1342a6744ebSBarry Smith        0,
1352a6744ebSBarry Smith        0,
1362a6744ebSBarry Smith        0,
1372a6744ebSBarry Smith        0,
1382a6744ebSBarry Smith /*20*/ 0,
1392a6744ebSBarry Smith        0,
1402a6744ebSBarry Smith        0,
1412a6744ebSBarry Smith        0,
142d519adbfSMatthew Knepley /*24*/ 0,
1432a6744ebSBarry Smith        0,
1442a6744ebSBarry Smith        0,
1452a6744ebSBarry Smith        0,
1462a6744ebSBarry Smith        0,
147d519adbfSMatthew Knepley /*29*/ 0,
1482a6744ebSBarry Smith        0,
1492a6744ebSBarry Smith        0,
1502a6744ebSBarry Smith        0,
1512a6744ebSBarry Smith        0,
152d519adbfSMatthew Knepley /*34*/ 0,
1532a6744ebSBarry Smith        0,
1542a6744ebSBarry Smith        0,
1552a6744ebSBarry Smith        0,
1562a6744ebSBarry Smith        0,
157d519adbfSMatthew Knepley /*39*/ 0,
1582a6744ebSBarry Smith        0,
1592a6744ebSBarry Smith        0,
1602a6744ebSBarry Smith        0,
1612a6744ebSBarry Smith        0,
162d519adbfSMatthew Knepley /*44*/ 0,
1632a6744ebSBarry Smith        0,
1642a6744ebSBarry Smith        0,
1652a6744ebSBarry Smith        0,
1662a6744ebSBarry Smith        0,
167d519adbfSMatthew Knepley /*49*/ 0,
1682a6744ebSBarry Smith        0,
1692a6744ebSBarry Smith        0,
1702a6744ebSBarry Smith        0,
1712a6744ebSBarry Smith        0,
172d519adbfSMatthew Knepley /*54*/ 0,
1732a6744ebSBarry Smith        0,
1742a6744ebSBarry Smith        0,
1752a6744ebSBarry Smith        0,
1762a6744ebSBarry Smith        0,
177d519adbfSMatthew Knepley /*59*/ 0,
1782a6744ebSBarry Smith        MatDestroy_Scatter,
1792a6744ebSBarry Smith        0,
1802a6744ebSBarry Smith        0,
1812a6744ebSBarry Smith        0,
182d519adbfSMatthew Knepley /*64*/ 0,
1832a6744ebSBarry Smith        0,
1842a6744ebSBarry Smith        0,
1852a6744ebSBarry Smith        0,
1862a6744ebSBarry Smith        0,
187d519adbfSMatthew Knepley /*69*/ 0,
1882a6744ebSBarry Smith        0,
1892a6744ebSBarry Smith        0,
1902a6744ebSBarry Smith        0,
1912a6744ebSBarry Smith        0,
192d519adbfSMatthew Knepley /*74*/ 0,
1932a6744ebSBarry Smith        0,
1942a6744ebSBarry Smith        0,
1952a6744ebSBarry Smith        0,
1962a6744ebSBarry Smith        0,
197d519adbfSMatthew Knepley /*79*/ 0,
1982a6744ebSBarry Smith        0,
1992a6744ebSBarry Smith        0,
2002a6744ebSBarry Smith        0,
2012a6744ebSBarry Smith        0,
202d519adbfSMatthew Knepley /*84*/ 0,
2032a6744ebSBarry Smith        0,
2042a6744ebSBarry Smith        0,
2052a6744ebSBarry Smith        0,
2062a6744ebSBarry Smith        0,
207d519adbfSMatthew Knepley /*89*/ 0,
2082a6744ebSBarry Smith        0,
2092a6744ebSBarry Smith        0,
2102a6744ebSBarry Smith        0,
2112a6744ebSBarry Smith        0,
212d519adbfSMatthew Knepley /*94*/ 0,
2132a6744ebSBarry Smith        0,
2142a6744ebSBarry Smith        0,
2152a6744ebSBarry Smith        0};
2162a6744ebSBarry Smith 
2172a6744ebSBarry Smith /*MC
2184a440b9bSBarry Smith    MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()
2192a6744ebSBarry Smith 
2202a6744ebSBarry Smith   Level: advanced
2212a6744ebSBarry Smith 
2222a6744ebSBarry Smith .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()
2232a6744ebSBarry Smith 
2242a6744ebSBarry Smith M*/
2252a6744ebSBarry Smith 
2262a6744ebSBarry Smith EXTERN_C_BEGIN
2272a6744ebSBarry Smith #undef __FUNCT__
2282a6744ebSBarry Smith #define __FUNCT__ "MatCreate_Scatter"
2292a6744ebSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Scatter(Mat A)
2302a6744ebSBarry Smith {
2312a6744ebSBarry Smith   Mat_Scatter    *b;
2322a6744ebSBarry Smith   PetscErrorCode ierr;
2332a6744ebSBarry Smith 
2342a6744ebSBarry Smith   PetscFunctionBegin;
2352a6744ebSBarry Smith   ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
23638f2d2fdSLisandro Dalcin   ierr = PetscNewLog(A,Mat_Scatter,&b);CHKERRQ(ierr);
2372a6744ebSBarry Smith 
2382a6744ebSBarry Smith   A->data = (void*)b;
2392a6744ebSBarry Smith 
24026283091SBarry Smith   ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr);
24126283091SBarry Smith   ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr);
24226283091SBarry Smith   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
24326283091SBarry Smith   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
2442a6744ebSBarry Smith 
2452a6744ebSBarry Smith   A->assembled     = PETSC_TRUE;
2462a6744ebSBarry Smith   A->preallocated  = PETSC_FALSE;
24774d95942SJed Brown 
24874d95942SJed Brown   ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);CHKERRQ(ierr);
2492a6744ebSBarry Smith   PetscFunctionReturn(0);
2502a6744ebSBarry Smith }
2512a6744ebSBarry Smith EXTERN_C_END
2522a6744ebSBarry Smith 
2532a6744ebSBarry Smith #undef __FUNCT__
2542a6744ebSBarry Smith #define __FUNCT__ "MatCreateScatter"
2552a6744ebSBarry Smith /*@C
2562a6744ebSBarry Smith    MatCreateScatter - Creates a new matrix based on a VecScatter
2572a6744ebSBarry Smith 
2582a6744ebSBarry Smith   Collective on MPI_Comm
2592a6744ebSBarry Smith 
2602a6744ebSBarry Smith    Input Parameters:
2612a6744ebSBarry Smith +  comm - MPI communicator
2622a6744ebSBarry Smith -  scatter - a VecScatterContext
2632a6744ebSBarry Smith 
2642a6744ebSBarry Smith    Output Parameter:
2652a6744ebSBarry Smith .  A - the matrix
2662a6744ebSBarry Smith 
2672a6744ebSBarry Smith    Level: intermediate
2682a6744ebSBarry Smith 
2692a6744ebSBarry Smith    PETSc requires that matrices and vectors being used for certain
2702a6744ebSBarry Smith    operations are partitioned accordingly.  For example, when
2712a6744ebSBarry Smith    creating a scatter matrix, A, that supports parallel matrix-vector
2722a6744ebSBarry Smith    products using MatMult(A,x,y) the user should set the number
2732a6744ebSBarry Smith    of local matrix rows to be the number of local elements of the
2742a6744ebSBarry Smith    corresponding result vector, y. Note that this is information is
2752a6744ebSBarry Smith    required for use of the matrix interface routines, even though
2762a6744ebSBarry Smith    the scatter matrix may not actually be physically partitioned.
2772a6744ebSBarry Smith    For example,
2782a6744ebSBarry Smith 
2792a6744ebSBarry Smith .keywords: matrix, scatter, create
2802a6744ebSBarry Smith 
2812a6744ebSBarry Smith .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
2822a6744ebSBarry Smith @*/
2832a6744ebSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
2842a6744ebSBarry Smith {
2852a6744ebSBarry Smith   PetscErrorCode ierr;
2862a6744ebSBarry Smith 
2872a6744ebSBarry Smith   PetscFunctionBegin;
2882a6744ebSBarry Smith   ierr = MatCreate(comm,A);CHKERRQ(ierr);
2892a6744ebSBarry Smith   ierr = MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
2902a6744ebSBarry Smith   ierr = MatSetType(*A,MATSCATTER);CHKERRQ(ierr);
2912a6744ebSBarry Smith   ierr = MatScatterSetVecScatter(*A,scatter);CHKERRQ(ierr);
2922a6744ebSBarry Smith   PetscFunctionReturn(0);
2932a6744ebSBarry Smith }
2942a6744ebSBarry Smith 
2952a6744ebSBarry Smith #undef __FUNCT__
2962a6744ebSBarry Smith #define __FUNCT__ "MatScatterSetVecScatter"
2972a6744ebSBarry Smith /*@
2982a6744ebSBarry Smith     MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator
2992a6744ebSBarry Smith 
3002a6744ebSBarry Smith    Collective on Mat
3012a6744ebSBarry Smith 
3022a6744ebSBarry Smith     Input Parameters:
3032a6744ebSBarry Smith +   mat - the scatter matrix
3042a6744ebSBarry Smith -   scatter - the scatter context create with VecScatterCreate()
3052a6744ebSBarry Smith 
3062a6744ebSBarry Smith    Level: advanced
3072a6744ebSBarry Smith 
3082a6744ebSBarry Smith 
3092a6744ebSBarry Smith .seealso: MatCreateScatter(), MATSCATTER
3102a6744ebSBarry Smith @*/
3112a6744ebSBarry Smith PetscErrorCode PETSCMAT_DLLEXPORT MatScatterSetVecScatter(Mat mat,VecScatter scatter)
3122a6744ebSBarry Smith {
3132a6744ebSBarry Smith   Mat_Scatter    *mscatter = (Mat_Scatter*)mat->data;
3142a6744ebSBarry Smith   PetscErrorCode ierr;
3152a6744ebSBarry Smith 
3162a6744ebSBarry Smith   PetscFunctionBegin;
317*0700a824SBarry Smith   PetscValidHeaderSpecific(mat,MAT_CLASSID,1);
318*0700a824SBarry Smith   PetscValidHeaderSpecific(scatter,VEC_SCATTER_CLASSID,2);
3194067f9b5SMatthew Knepley   PetscCheckSameComm((PetscObject)scatter,1,(PetscObject)mat,2);
320d0f46423SBarry Smith   if (mat->rmap->n != scatter->to_n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Number of local rows in matrix %D not equal local scatter size %D",mat->rmap->n,scatter->to_n);
321d0f46423SBarry Smith   if (mat->cmap->n != scatter->from_n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Number of local columns in matrix %D not equal local scatter size %D",mat->cmap->n,scatter->from_n);
3222a6744ebSBarry Smith 
323c3122656SLisandro Dalcin   ierr = PetscObjectReference((PetscObject)scatter);CHKERRQ(ierr);
3242a6744ebSBarry Smith   if (mscatter->scatter) {ierr = VecScatterDestroy(mscatter->scatter);CHKERRQ(ierr);}
3252a6744ebSBarry Smith   mscatter->scatter = scatter;
3262a6744ebSBarry Smith   PetscFunctionReturn(0);
3272a6744ebSBarry Smith }
3282a6744ebSBarry Smith 
3292a6744ebSBarry Smith 
330