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