xref: /petsc/src/mat/impls/scatter/mscatter.c (revision feff33ee0b5b037fa8f9f294dede656a2f85cc47)
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