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