12a6744ebSBarry Smith 22a6744ebSBarry Smith /* 32a6744ebSBarry Smith This provides a matrix that applies a VecScatter to a vector. 42a6744ebSBarry Smith */ 52a6744ebSBarry Smith 6af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 7af0996ceSBarry Smith #include <petsc/private/vecimpl.h> 82a6744ebSBarry Smith 92a6744ebSBarry Smith typedef struct { 102a6744ebSBarry Smith VecScatter scatter; 112a6744ebSBarry Smith } Mat_Scatter; 122a6744ebSBarry Smith 132a6744ebSBarry Smith /*@ 142a6744ebSBarry Smith MatScatterGetVecScatter - Returns the user-provided scatter set with MatScatterSetVecScatter() 152a6744ebSBarry Smith 162a6744ebSBarry Smith Not Collective, but not cannot use scatter if not used collectively on Mat 172a6744ebSBarry Smith 182a6744ebSBarry Smith Input Parameter: 192a6744ebSBarry Smith . mat - the matrix, should have been created with MatCreateScatter() or have type MATSCATTER 202a6744ebSBarry Smith 212a6744ebSBarry Smith Output Parameter: 222a6744ebSBarry Smith . scatter - the scatter context 232a6744ebSBarry Smith 242a6744ebSBarry Smith Level: intermediate 252a6744ebSBarry Smith 262a6744ebSBarry Smith .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER 272a6744ebSBarry Smith @*/ 287087cfbeSBarry Smith PetscErrorCode MatScatterGetVecScatter(Mat mat,VecScatter *scatter) 292a6744ebSBarry Smith { 302a6744ebSBarry Smith Mat_Scatter *mscatter; 312a6744ebSBarry Smith 322a6744ebSBarry Smith PetscFunctionBegin; 330700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 342a6744ebSBarry Smith PetscValidPointer(scatter,2); 352a6744ebSBarry Smith mscatter = (Mat_Scatter*)mat->data; 362a6744ebSBarry Smith *scatter = mscatter->scatter; 372a6744ebSBarry Smith PetscFunctionReturn(0); 382a6744ebSBarry Smith } 392a6744ebSBarry Smith 402a6744ebSBarry Smith PetscErrorCode MatDestroy_Scatter(Mat mat) 412a6744ebSBarry Smith { 422a6744ebSBarry Smith PetscErrorCode ierr; 432a6744ebSBarry Smith Mat_Scatter *scatter = (Mat_Scatter*)mat->data; 442a6744ebSBarry Smith 452a6744ebSBarry Smith PetscFunctionBegin; 466bf464f9SBarry Smith ierr = VecScatterDestroy(&scatter->scatter);CHKERRQ(ierr); 476bf464f9SBarry Smith ierr = PetscFree(mat->data);CHKERRQ(ierr); 482a6744ebSBarry Smith PetscFunctionReturn(0); 492a6744ebSBarry Smith } 502a6744ebSBarry Smith 512a6744ebSBarry Smith PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y) 522a6744ebSBarry Smith { 532a6744ebSBarry Smith Mat_Scatter *scatter = (Mat_Scatter*)A->data; 542a6744ebSBarry Smith PetscErrorCode ierr; 552a6744ebSBarry Smith 562a6744ebSBarry Smith PetscFunctionBegin; 57ce94432eSBarry Smith if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 5874d95942SJed Brown ierr = VecZeroEntries(y);CHKERRQ(ierr); 5974d95942SJed Brown ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6074d95942SJed Brown ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 612a6744ebSBarry Smith PetscFunctionReturn(0); 622a6744ebSBarry Smith } 632a6744ebSBarry Smith 642a6744ebSBarry Smith PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z) 652a6744ebSBarry Smith { 662a6744ebSBarry Smith Mat_Scatter *scatter = (Mat_Scatter*)A->data; 672a6744ebSBarry Smith PetscErrorCode ierr; 682a6744ebSBarry Smith 692a6744ebSBarry Smith PetscFunctionBegin; 70ce94432eSBarry Smith if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 712a6744ebSBarry Smith if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);} 72ca9f406cSSatish Balay ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 73ca9f406cSSatish Balay ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 742a6744ebSBarry Smith PetscFunctionReturn(0); 752a6744ebSBarry Smith } 762a6744ebSBarry Smith 772a6744ebSBarry Smith PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y) 782a6744ebSBarry Smith { 792a6744ebSBarry Smith Mat_Scatter *scatter = (Mat_Scatter*)A->data; 802a6744ebSBarry Smith PetscErrorCode ierr; 812a6744ebSBarry Smith 822a6744ebSBarry Smith PetscFunctionBegin; 83ce94432eSBarry Smith if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 8474d95942SJed Brown ierr = VecZeroEntries(y);CHKERRQ(ierr); 8574d95942SJed Brown ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8674d95942SJed Brown ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 872a6744ebSBarry Smith PetscFunctionReturn(0); 882a6744ebSBarry Smith } 892a6744ebSBarry Smith 902a6744ebSBarry Smith PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z) 912a6744ebSBarry Smith { 922a6744ebSBarry Smith Mat_Scatter *scatter = (Mat_Scatter*)A->data; 932a6744ebSBarry Smith PetscErrorCode ierr; 942a6744ebSBarry Smith 952a6744ebSBarry Smith PetscFunctionBegin; 96ce94432eSBarry Smith if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 972a6744ebSBarry Smith if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);} 98ca9f406cSSatish Balay ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 99ca9f406cSSatish Balay ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 1002a6744ebSBarry Smith PetscFunctionReturn(0); 1012a6744ebSBarry Smith } 1022a6744ebSBarry Smith 1032a6744ebSBarry Smith static struct _MatOps MatOps_Values = {0, 1042a6744ebSBarry Smith 0, 1052a6744ebSBarry Smith 0, 1062a6744ebSBarry Smith MatMult_Scatter, 1072a6744ebSBarry Smith /* 4*/ MatMultAdd_Scatter, 1082a6744ebSBarry Smith MatMultTranspose_Scatter, 1092a6744ebSBarry Smith MatMultTransposeAdd_Scatter, 1102a6744ebSBarry Smith 0, 1112a6744ebSBarry Smith 0, 1122a6744ebSBarry Smith 0, 1132a6744ebSBarry Smith /* 10*/ 0, 1142a6744ebSBarry Smith 0, 1152a6744ebSBarry Smith 0, 1162a6744ebSBarry Smith 0, 1172a6744ebSBarry Smith 0, 1182a6744ebSBarry Smith /* 15*/ 0, 1192a6744ebSBarry Smith 0, 1202a6744ebSBarry Smith 0, 1212a6744ebSBarry Smith 0, 1222a6744ebSBarry Smith 0, 1232a6744ebSBarry Smith /* 20*/ 0, 1242a6744ebSBarry Smith 0, 1252a6744ebSBarry Smith 0, 1262a6744ebSBarry Smith 0, 127d519adbfSMatthew Knepley /* 24*/ 0, 1282a6744ebSBarry Smith 0, 1292a6744ebSBarry Smith 0, 1302a6744ebSBarry Smith 0, 1312a6744ebSBarry Smith 0, 132d519adbfSMatthew Knepley /* 29*/ 0, 1332a6744ebSBarry Smith 0, 1342a6744ebSBarry Smith 0, 1352a6744ebSBarry Smith 0, 1362a6744ebSBarry Smith 0, 137d519adbfSMatthew Knepley /* 34*/ 0, 1382a6744ebSBarry Smith 0, 1392a6744ebSBarry Smith 0, 1402a6744ebSBarry Smith 0, 1412a6744ebSBarry Smith 0, 142d519adbfSMatthew Knepley /* 39*/ 0, 1432a6744ebSBarry Smith 0, 1442a6744ebSBarry Smith 0, 1452a6744ebSBarry Smith 0, 1462a6744ebSBarry Smith 0, 147d519adbfSMatthew Knepley /* 44*/ 0, 1482a6744ebSBarry Smith 0, 1497d68702bSBarry Smith MatShift_Basic, 1502a6744ebSBarry Smith 0, 1512a6744ebSBarry Smith 0, 152d519adbfSMatthew Knepley /* 49*/ 0, 1532a6744ebSBarry Smith 0, 1542a6744ebSBarry Smith 0, 1552a6744ebSBarry Smith 0, 1562a6744ebSBarry Smith 0, 157d519adbfSMatthew Knepley /* 54*/ 0, 1582a6744ebSBarry Smith 0, 1592a6744ebSBarry Smith 0, 1602a6744ebSBarry Smith 0, 1612a6744ebSBarry Smith 0, 162d519adbfSMatthew Knepley /* 59*/ 0, 1632a6744ebSBarry Smith MatDestroy_Scatter, 1642a6744ebSBarry Smith 0, 1652a6744ebSBarry Smith 0, 1662a6744ebSBarry Smith 0, 167d519adbfSMatthew Knepley /* 64*/ 0, 1682a6744ebSBarry Smith 0, 1692a6744ebSBarry Smith 0, 1702a6744ebSBarry Smith 0, 1712a6744ebSBarry Smith 0, 172d519adbfSMatthew Knepley /* 69*/ 0, 1732a6744ebSBarry Smith 0, 1742a6744ebSBarry Smith 0, 1752a6744ebSBarry Smith 0, 1762a6744ebSBarry Smith 0, 177d519adbfSMatthew Knepley /* 74*/ 0, 1782a6744ebSBarry Smith 0, 1792a6744ebSBarry Smith 0, 1802a6744ebSBarry Smith 0, 1812a6744ebSBarry Smith 0, 182d519adbfSMatthew Knepley /* 79*/ 0, 1832a6744ebSBarry Smith 0, 1842a6744ebSBarry Smith 0, 1852a6744ebSBarry Smith 0, 1862a6744ebSBarry Smith 0, 187d519adbfSMatthew Knepley /* 84*/ 0, 1882a6744ebSBarry Smith 0, 1892a6744ebSBarry Smith 0, 1902a6744ebSBarry Smith 0, 1912a6744ebSBarry Smith 0, 192d519adbfSMatthew Knepley /* 89*/ 0, 1932a6744ebSBarry Smith 0, 1942a6744ebSBarry Smith 0, 1952a6744ebSBarry Smith 0, 1962a6744ebSBarry Smith 0, 197d519adbfSMatthew Knepley /* 94*/ 0, 1982a6744ebSBarry Smith 0, 1992a6744ebSBarry Smith 0, 2003964eb88SJed Brown 0, 2013964eb88SJed Brown 0, 2023964eb88SJed Brown /*99*/ 0, 2033964eb88SJed Brown 0, 2043964eb88SJed Brown 0, 2053964eb88SJed Brown 0, 2063964eb88SJed Brown 0, 2073964eb88SJed Brown /*104*/ 0, 2083964eb88SJed Brown 0, 2093964eb88SJed Brown 0, 2103964eb88SJed Brown 0, 2113964eb88SJed Brown 0, 2123964eb88SJed Brown /*109*/ 0, 2133964eb88SJed Brown 0, 2143964eb88SJed Brown 0, 2153964eb88SJed Brown 0, 2163964eb88SJed Brown 0, 2173964eb88SJed Brown /*114*/ 0, 2183964eb88SJed Brown 0, 2193964eb88SJed Brown 0, 2203964eb88SJed Brown 0, 2213964eb88SJed Brown 0, 2223964eb88SJed Brown /*119*/ 0, 2233964eb88SJed Brown 0, 2243964eb88SJed Brown 0, 2253964eb88SJed Brown 0, 2263964eb88SJed Brown 0, 2273964eb88SJed Brown /*124*/ 0, 2283964eb88SJed Brown 0, 2293964eb88SJed Brown 0, 2303964eb88SJed Brown 0, 2313964eb88SJed Brown 0, 2323964eb88SJed Brown /*129*/ 0, 2333964eb88SJed Brown 0, 2343964eb88SJed Brown 0, 2353964eb88SJed Brown 0, 2363964eb88SJed Brown 0, 2373964eb88SJed Brown /*134*/ 0, 2383964eb88SJed Brown 0, 2393964eb88SJed Brown 0, 2403964eb88SJed Brown 0, 2413964eb88SJed Brown 0, 2423964eb88SJed Brown /*139*/ 0, 243f9426fe0SMark Adams 0, 2443964eb88SJed Brown 0 2453964eb88SJed Brown }; 2462a6744ebSBarry Smith 2472a6744ebSBarry Smith /*MC 2484a440b9bSBarry Smith MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End() 2492a6744ebSBarry Smith 2502a6744ebSBarry Smith Level: advanced 2512a6744ebSBarry Smith 2522a6744ebSBarry Smith .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter() 2532a6744ebSBarry Smith 2542a6744ebSBarry Smith M*/ 2552a6744ebSBarry Smith 2568cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A) 2572a6744ebSBarry Smith { 2582a6744ebSBarry Smith Mat_Scatter *b; 2592a6744ebSBarry Smith PetscErrorCode ierr; 2602a6744ebSBarry Smith 2612a6744ebSBarry Smith PetscFunctionBegin; 2622a6744ebSBarry Smith ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 263b00a9115SJed Brown ierr = PetscNewLog(A,&b);CHKERRQ(ierr); 2642a6744ebSBarry Smith 2652a6744ebSBarry Smith A->data = (void*)b; 2662a6744ebSBarry Smith 26726283091SBarry Smith ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 26826283091SBarry Smith ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 2692a6744ebSBarry Smith 2702a6744ebSBarry Smith A->assembled = PETSC_TRUE; 2712a6744ebSBarry Smith A->preallocated = PETSC_FALSE; 27274d95942SJed Brown 27374d95942SJed Brown ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);CHKERRQ(ierr); 2742a6744ebSBarry Smith PetscFunctionReturn(0); 2752a6744ebSBarry Smith } 2762a6744ebSBarry Smith 2776eb45d04SBarry Smith #include <petsc/private/vecscatterimpl.h> 2782a6744ebSBarry Smith /*@C 2792a6744ebSBarry Smith MatCreateScatter - Creates a new matrix based on a VecScatter 2802a6744ebSBarry Smith 281*d083f849SBarry Smith Collective 2822a6744ebSBarry Smith 2832a6744ebSBarry Smith Input Parameters: 2842a6744ebSBarry Smith + comm - MPI communicator 2852a6744ebSBarry Smith - scatter - a VecScatterContext 2862a6744ebSBarry Smith 2872a6744ebSBarry Smith Output Parameter: 2882a6744ebSBarry Smith . A - the matrix 2892a6744ebSBarry Smith 2902a6744ebSBarry Smith Level: intermediate 2912a6744ebSBarry Smith 2922a6744ebSBarry Smith PETSc requires that matrices and vectors being used for certain 2932a6744ebSBarry Smith operations are partitioned accordingly. For example, when 2942a6744ebSBarry Smith creating a scatter matrix, A, that supports parallel matrix-vector 2952a6744ebSBarry Smith products using MatMult(A,x,y) the user should set the number 2962a6744ebSBarry Smith of local matrix rows to be the number of local elements of the 2972a6744ebSBarry Smith corresponding result vector, y. Note that this is information is 2982a6744ebSBarry Smith required for use of the matrix interface routines, even though 2992a6744ebSBarry Smith the scatter matrix may not actually be physically partitioned. 3002a6744ebSBarry Smith 3016eb45d04SBarry Smith Developer Notes: This directly accesses information inside the VecScatter associated with the matrix-vector product 3026eb45d04SBarry Smith for this matrix. This is not desirable.. 3036eb45d04SBarry Smith 3046eb45d04SBarry Smith 3052a6744ebSBarry Smith .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER 3062a6744ebSBarry Smith @*/ 3077087cfbeSBarry Smith PetscErrorCode MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A) 3082a6744ebSBarry Smith { 3092a6744ebSBarry Smith PetscErrorCode ierr; 3102a6744ebSBarry Smith 3112a6744ebSBarry Smith PetscFunctionBegin; 3122a6744ebSBarry Smith ierr = MatCreate(comm,A);CHKERRQ(ierr); 3132a6744ebSBarry Smith ierr = MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 3142a6744ebSBarry Smith ierr = MatSetType(*A,MATSCATTER);CHKERRQ(ierr); 3152a6744ebSBarry Smith ierr = MatScatterSetVecScatter(*A,scatter);CHKERRQ(ierr); 31637e1895aSJed Brown ierr = MatSetUp(*A);CHKERRQ(ierr); 3172a6744ebSBarry Smith PetscFunctionReturn(0); 3182a6744ebSBarry Smith } 3192a6744ebSBarry Smith 3202a6744ebSBarry Smith /*@ 3212a6744ebSBarry Smith MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator 3222a6744ebSBarry Smith 3232a6744ebSBarry Smith Collective on Mat 3242a6744ebSBarry Smith 3252a6744ebSBarry Smith Input Parameters: 3262a6744ebSBarry Smith + mat - the scatter matrix 3279448b7f1SJunchao Zhang - scatter - the scatter context create with VecScatterCreate() 3282a6744ebSBarry Smith 3292a6744ebSBarry Smith Level: advanced 3302a6744ebSBarry Smith 3312a6744ebSBarry Smith 3322a6744ebSBarry Smith .seealso: MatCreateScatter(), MATSCATTER 3332a6744ebSBarry Smith @*/ 3347087cfbeSBarry Smith PetscErrorCode MatScatterSetVecScatter(Mat mat,VecScatter scatter) 3352a6744ebSBarry Smith { 3362a6744ebSBarry Smith Mat_Scatter *mscatter = (Mat_Scatter*)mat->data; 3372a6744ebSBarry Smith PetscErrorCode ierr; 3382a6744ebSBarry Smith 3392a6744ebSBarry Smith PetscFunctionBegin; 3400700a824SBarry Smith PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 3410700a824SBarry Smith PetscValidHeaderSpecific(scatter,VEC_SCATTER_CLASSID,2); 3424067f9b5SMatthew Knepley PetscCheckSameComm((PetscObject)scatter,1,(PetscObject)mat,2); 343e32f2f54SBarry Smith if (mat->rmap->n != scatter->to_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local rows in matrix %D not equal local scatter size %D",mat->rmap->n,scatter->to_n); 344e32f2f54SBarry Smith if (mat->cmap->n != scatter->from_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local columns in matrix %D not equal local scatter size %D",mat->cmap->n,scatter->from_n); 3452a6744ebSBarry Smith 346c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)scatter);CHKERRQ(ierr); 3476bf464f9SBarry Smith ierr = VecScatterDestroy(&mscatter->scatter);CHKERRQ(ierr); 34826fbe8dcSKarl Rupp 3492a6744ebSBarry Smith mscatter->scatter = scatter; 3502a6744ebSBarry Smith PetscFunctionReturn(0); 3512a6744ebSBarry Smith } 3522a6744ebSBarry Smith 3532a6744ebSBarry Smith 354