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