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