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 /*@C 280 MatCreateScatter - Creates a new matrix based on a VecScatter 281 282 Collective on MPI_Comm 283 284 Input Parameters: 285 + comm - MPI communicator 286 - scatter - a VecScatterContext 287 288 Output Parameter: 289 . A - the matrix 290 291 Level: intermediate 292 293 PETSc requires that matrices and vectors being used for certain 294 operations are partitioned accordingly. For example, when 295 creating a scatter matrix, A, that supports parallel matrix-vector 296 products using MatMult(A,x,y) the user should set the number 297 of local matrix rows to be the number of local elements of the 298 corresponding result vector, y. Note that this is information is 299 required for use of the matrix interface routines, even though 300 the scatter matrix may not actually be physically partitioned. 301 302 .keywords: matrix, scatter, create 303 304 .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER 305 @*/ 306 PetscErrorCode MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A) 307 { 308 PetscErrorCode ierr; 309 310 PetscFunctionBegin; 311 ierr = MatCreate(comm,A);CHKERRQ(ierr); 312 ierr = MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr); 313 ierr = MatSetType(*A,MATSCATTER);CHKERRQ(ierr); 314 ierr = MatScatterSetVecScatter(*A,scatter);CHKERRQ(ierr); 315 ierr = MatSetUp(*A);CHKERRQ(ierr); 316 PetscFunctionReturn(0); 317 } 318 319 /*@ 320 MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator 321 322 Collective on Mat 323 324 Input Parameters: 325 + mat - the scatter matrix 326 - scatter - the scatter context create with VecScatterCreate() 327 328 Level: advanced 329 330 331 .seealso: MatCreateScatter(), MATSCATTER 332 @*/ 333 PetscErrorCode MatScatterSetVecScatter(Mat mat,VecScatter scatter) 334 { 335 Mat_Scatter *mscatter = (Mat_Scatter*)mat->data; 336 PetscErrorCode ierr; 337 338 PetscFunctionBegin; 339 PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 340 PetscValidHeaderSpecific(scatter,VEC_SCATTER_CLASSID,2); 341 PetscCheckSameComm((PetscObject)scatter,1,(PetscObject)mat,2); 342 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); 343 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); 344 345 ierr = PetscObjectReference((PetscObject)scatter);CHKERRQ(ierr); 346 ierr = VecScatterDestroy(&mscatter->scatter);CHKERRQ(ierr); 347 348 mscatter->scatter = scatter; 349 PetscFunctionReturn(0); 350 } 351 352 353