xref: /petsc/src/mat/impls/scatter/mscatter.c (revision 91e63d38360eb9bc922f79d792328cc4769c01ac)
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 @*/
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 
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 
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   PetscCheckFalse(!scatter->scatter,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 
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   PetscCheckFalse(!scatter->scatter,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 
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   PetscCheckFalse(!scatter->scatter,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 
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   PetscCheckFalse(!scatter->scatter,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                                        NULL,
246                                        NULL,
247                                 /*144*/NULL,
248                                        NULL,
249                                        NULL,
250                                        NULL
251 };
252 
253 /*MC
254    MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()
255 
256   Level: advanced
257 
258 .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()
259 
260 M*/
261 
262 PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
263 {
264   Mat_Scatter    *b;
265   PetscErrorCode ierr;
266 
267   PetscFunctionBegin;
268   ierr = PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr);
269   ierr = PetscNewLog(A,&b);CHKERRQ(ierr);
270 
271   A->data = (void*)b;
272 
273   ierr = PetscLayoutSetUp(A->rmap);CHKERRQ(ierr);
274   ierr = PetscLayoutSetUp(A->cmap);CHKERRQ(ierr);
275 
276   A->assembled    = PETSC_TRUE;
277   A->preallocated = PETSC_FALSE;
278 
279   ierr = PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);CHKERRQ(ierr);
280   PetscFunctionReturn(0);
281 }
282 
283 #include <petsc/private/sfimpl.h>
284 /*@C
285    MatCreateScatter - Creates a new matrix based on a VecScatter
286 
287   Collective
288 
289    Input Parameters:
290 +  comm - MPI communicator
291 -  scatter - a VecScatterContext
292 
293    Output Parameter:
294 .  A - the matrix
295 
296    Level: intermediate
297 
298    PETSc requires that matrices and vectors being used for certain
299    operations are partitioned accordingly.  For example, when
300    creating a scatter matrix, A, that supports parallel matrix-vector
301    products using MatMult(A,x,y) the user should set the number
302    of local matrix rows to be the number of local elements of the
303    corresponding result vector, y. Note that this is information is
304    required for use of the matrix interface routines, even though
305    the scatter matrix may not actually be physically partitioned.
306 
307   Developer Notes: This directly accesses information inside the VecScatter associated with the matrix-vector product
308    for this matrix. This is not desirable..
309 
310 .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
311 @*/
312 PetscErrorCode  MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
313 {
314   PetscErrorCode ierr;
315 
316   PetscFunctionBegin;
317   ierr = MatCreate(comm,A);CHKERRQ(ierr);
318   ierr = MatSetSizes(*A,scatter->vscat.to_n,scatter->vscat.from_n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);
319   ierr = MatSetType(*A,MATSCATTER);CHKERRQ(ierr);
320   ierr = MatScatterSetVecScatter(*A,scatter);CHKERRQ(ierr);
321   ierr = MatSetUp(*A);CHKERRQ(ierr);
322   PetscFunctionReturn(0);
323 }
324 
325 /*@
326     MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator
327 
328    Collective on Mat
329 
330     Input Parameters:
331 +   mat - the scatter matrix
332 -   scatter - the scatter context create with VecScatterCreate()
333 
334    Level: advanced
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,PETSCSF_CLASSID,2);
346   PetscCheckSameComm((PetscObject)scatter,2,(PetscObject)mat,1);
347   PetscCheckFalse(mat->rmap->n != scatter->vscat.to_n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local rows in matrix %" PetscInt_FMT " not equal local scatter size %" PetscInt_FMT,mat->rmap->n,scatter->vscat.to_n);
348   PetscCheckFalse(mat->cmap->n != scatter->vscat.from_n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local columns in matrix %" PetscInt_FMT " not equal local scatter size %" PetscInt_FMT,mat->cmap->n,scatter->vscat.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