1 #define PETSCMAT_DLL 2 3 /* 4 This provides a matrix that applies a VecScatter to a vector. 5 */ 6 7 #include "private/matimpl.h" /*I "petscmat.h" I*/ 8 #include "private/vecimpl.h" 9 10 typedef struct { 11 VecScatter scatter; 12 } Mat_Scatter; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "MatScatterGetVecScatter" 16 /*@ 17 MatScatterGetVecScatter - Returns the user-provided scatter set with MatScatterSetVecScatter() 18 19 Not Collective, but not cannot use scatter if not used collectively on Mat 20 21 Input Parameter: 22 . mat - the matrix, should have been created with MatCreateScatter() or have type MATSCATTER 23 24 Output Parameter: 25 . scatter - the scatter context 26 27 Level: intermediate 28 29 .keywords: matrix, scatter, get 30 31 .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER 32 @*/ 33 PetscErrorCode PETSCMAT_DLLEXPORT MatScatterGetVecScatter(Mat mat,VecScatter *scatter) 34 { 35 Mat_Scatter *mscatter; 36 37 PetscFunctionBegin; 38 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 39 PetscValidPointer(scatter,2); 40 mscatter = (Mat_Scatter*)mat->data; 41 *scatter = mscatter->scatter; 42 PetscFunctionReturn(0); 43 } 44 45 #undef __FUNCT__ 46 #define __FUNCT__ "MatDestroy_Scatter" 47 PetscErrorCode MatDestroy_Scatter(Mat mat) 48 { 49 PetscErrorCode ierr; 50 Mat_Scatter *scatter = (Mat_Scatter*)mat->data; 51 52 PetscFunctionBegin; 53 if (scatter->scatter) {ierr = VecScatterDestroy(scatter->scatter);CHKERRQ(ierr);} 54 ierr = PetscFree(scatter);CHKERRQ(ierr); 55 PetscFunctionReturn(0); 56 } 57 58 #undef __FUNCT__ 59 #define __FUNCT__ "MatMult_Scatter" 60 PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y) 61 { 62 Mat_Scatter *scatter = (Mat_Scatter*)A->data; 63 PetscErrorCode ierr; 64 65 PetscFunctionBegin; 66 if (!scatter->scatter) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 67 ierr = VecZeroEntries(y);CHKERRQ(ierr); 68 ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 69 ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 70 PetscFunctionReturn(0); 71 } 72 73 #undef __FUNCT__ 74 #define __FUNCT__ "MatMultAdd_Scatter" 75 PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z) 76 { 77 Mat_Scatter *scatter = (Mat_Scatter*)A->data; 78 PetscErrorCode ierr; 79 80 PetscFunctionBegin; 81 if (!scatter->scatter) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 82 if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);} 83 ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 84 ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 85 PetscFunctionReturn(0); 86 } 87 88 #undef __FUNCT__ 89 #define __FUNCT__ "MatMultTranspose_Scatter" 90 PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y) 91 { 92 Mat_Scatter *scatter = (Mat_Scatter*)A->data; 93 PetscErrorCode ierr; 94 95 PetscFunctionBegin; 96 if (!scatter->scatter) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 97 ierr = VecZeroEntries(y);CHKERRQ(ierr); 98 ierr = VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 99 ierr = VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "MatMultTransposeAdd_Scatter" 105 PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z) 106 { 107 Mat_Scatter *scatter = (Mat_Scatter*)A->data; 108 PetscErrorCode ierr; 109 110 PetscFunctionBegin; 111 if (!scatter->scatter) SETERRQ(((PetscObject)A)->comm,PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()"); 112 if (z != y) {ierr = VecCopy(y,z);CHKERRQ(ierr);} 113 ierr = VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 114 ierr = VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 115 PetscFunctionReturn(0); 116 } 117 118 static struct _MatOps MatOps_Values = {0, 119 0, 120 0, 121 MatMult_Scatter, 122 /* 4*/ MatMultAdd_Scatter, 123 MatMultTranspose_Scatter, 124 MatMultTransposeAdd_Scatter, 125 0, 126 0, 127 0, 128 /*10*/ 0, 129 0, 130 0, 131 0, 132 0, 133 /*15*/ 0, 134 0, 135 0, 136 0, 137 0, 138 /*20*/ 0, 139 0, 140 0, 141 0, 142 /*24*/ 0, 143 0, 144 0, 145 0, 146 0, 147 /*29*/ 0, 148 0, 149 0, 150 0, 151 0, 152 /*34*/ 0, 153 0, 154 0, 155 0, 156 0, 157 /*39*/ 0, 158 0, 159 0, 160 0, 161 0, 162 /*44*/ 0, 163 0, 164 0, 165 0, 166 0, 167 /*49*/ 0, 168 0, 169 0, 170 0, 171 0, 172 /*54*/ 0, 173 0, 174 0, 175 0, 176 0, 177 /*59*/ 0, 178 MatDestroy_Scatter, 179 0, 180 0, 181 0, 182 /*64*/ 0, 183 0, 184 0, 185 0, 186 0, 187 /*69*/ 0, 188 0, 189 0, 190 0, 191 0, 192 /*74*/ 0, 193 0, 194 0, 195 0, 196 0, 197 /*79*/ 0, 198 0, 199 0, 200 0, 201 0, 202 /*84*/ 0, 203 0, 204 0, 205 0, 206 0, 207 /*89*/ 0, 208 0, 209 0, 210 0, 211 0, 212 /*94*/ 0, 213 0, 214 0, 215 0}; 216 217 /*MC 218 MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End() 219 220 Level: advanced 221 222 .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter() 223 224 M*/ 225 226 EXTERN_C_BEGIN 227 #undef __FUNCT__ 228 #define __FUNCT__ "MatCreate_Scatter" 229 PetscErrorCode PETSCMAT_DLLEXPORT MatCreate_Scatter(Mat A) 230 { 231 Mat_Scatter *b; 232 PetscErrorCode ierr; 233 234 PetscFunctionBegin; 235 ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 236 ierr = PetscNewLog(A,Mat_Scatter,&b);CHKERRQ(ierr); 237 238 A->data = (void*)b; 239 240 ierr = PetscLayoutSetBlockSize(A->rmap,1);CHKERRQ(ierr); 241 ierr = PetscLayoutSetBlockSize(A->cmap,1);CHKERRQ(ierr); 242 ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr); 243 ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr); 244 245 A->assembled = PETSC_TRUE; 246 A->preallocated = PETSC_FALSE; 247 248 ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);CHKERRQ(ierr); 249 PetscFunctionReturn(0); 250 } 251 EXTERN_C_END 252 253 #undef __FUNCT__ 254 #define __FUNCT__ "MatCreateScatter" 255 /*@C 256 MatCreateScatter - Creates a new matrix based on a VecScatter 257 258 Collective on MPI_Comm 259 260 Input Parameters: 261 + comm - MPI communicator 262 - scatter - a VecScatterContext 263 264 Output Parameter: 265 . A - the matrix 266 267 Level: intermediate 268 269 PETSc requires that matrices and vectors being used for certain 270 operations are partitioned accordingly. For example, when 271 creating a scatter matrix, A, that supports parallel matrix-vector 272 products using MatMult(A,x,y) the user should set the number 273 of local matrix rows to be the number of local elements of the 274 corresponding result vector, y. Note that this is information is 275 required for use of the matrix interface routines, even though 276 the scatter matrix may not actually be physically partitioned. 277 For example, 278 279 .keywords: matrix, scatter, create 280 281 .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER 282 @*/ 283 PetscErrorCode PETSCMAT_DLLEXPORT MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A) 284 { 285 PetscErrorCode ierr; 286 287 PetscFunctionBegin; 288 ierr = MatCreate(comm,A);CHKERRQ(ierr); 289 ierr = MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 290 ierr = MatSetType(*A,MATSCATTER);CHKERRQ(ierr); 291 ierr = MatScatterSetVecScatter(*A,scatter);CHKERRQ(ierr); 292 PetscFunctionReturn(0); 293 } 294 295 #undef __FUNCT__ 296 #define __FUNCT__ "MatScatterSetVecScatter" 297 /*@ 298 MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator 299 300 Collective on Mat 301 302 Input Parameters: 303 + mat - the scatter matrix 304 - scatter - the scatter context create with VecScatterCreate() 305 306 Level: advanced 307 308 309 .seealso: MatCreateScatter(), MATSCATTER 310 @*/ 311 PetscErrorCode PETSCMAT_DLLEXPORT MatScatterSetVecScatter(Mat mat,VecScatter scatter) 312 { 313 Mat_Scatter *mscatter = (Mat_Scatter*)mat->data; 314 PetscErrorCode ierr; 315 316 PetscFunctionBegin; 317 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 318 PetscValidHeaderSpecific(scatter,VEC_SCATTER_CLASSID,2); 319 PetscCheckSameComm((PetscObject)scatter,1,(PetscObject)mat,2); 320 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); 321 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); 322 323 ierr = PetscObjectReference((PetscObject)scatter);CHKERRQ(ierr); 324 if (mscatter->scatter) {ierr = VecScatterDestroy(mscatter->scatter);CHKERRQ(ierr);} 325 mscatter->scatter = scatter; 326 PetscFunctionReturn(0); 327 } 328 329 330