Actual source code: mscatter.c


  2: /*
  3:    This provides a matrix that applies a VecScatter to a vector.
  4: */

  6: #include <petsc/private/matimpl.h>
  7: #include <petsc/private/vecimpl.h>

  9: typedef struct {
 10:   VecScatter scatter;
 11: } Mat_Scatter;

 13: /*@
 14:     MatScatterGetVecScatter - Returns the user-provided scatter set with `MatScatterSetVecScatter()` in a `MATSCATTER` matrix

 16:     Not Collective, but not cannot use scatter if not used collectively on `Mat`

 18:     Input Parameter:
 19: .   mat - the matrix, should have been created with MatCreateScatter() or have type `MATSCATTER`

 21:     Output Parameter:
 22: .   scatter - the scatter context

 24:     Level: intermediate

 26: .seealso: `MATSCATTER`, `MatCreateScatter()`, `MatScatterSetVecScatter()`, `MATSCATTER`
 27: @*/
 28: PetscErrorCode MatScatterGetVecScatter(Mat mat, VecScatter *scatter)
 29: {
 30:   Mat_Scatter *mscatter;

 34:   mscatter = (Mat_Scatter *)mat->data;
 35:   *scatter = mscatter->scatter;
 36:   return 0;
 37: }

 39: PetscErrorCode MatDestroy_Scatter(Mat mat)
 40: {
 41:   Mat_Scatter *scatter = (Mat_Scatter *)mat->data;

 43:   VecScatterDestroy(&scatter->scatter);
 44:   PetscFree(mat->data);
 45:   return 0;
 46: }

 48: PetscErrorCode MatMult_Scatter(Mat A, Vec x, Vec y)
 49: {
 50:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 53:   VecZeroEntries(y);
 54:   VecScatterBegin(scatter->scatter, x, y, ADD_VALUES, SCATTER_FORWARD);
 55:   VecScatterEnd(scatter->scatter, x, y, ADD_VALUES, SCATTER_FORWARD);
 56:   return 0;
 57: }

 59: PetscErrorCode MatMultAdd_Scatter(Mat A, Vec x, Vec y, Vec z)
 60: {
 61:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 64:   if (z != y) VecCopy(y, z);
 65:   VecScatterBegin(scatter->scatter, x, z, ADD_VALUES, SCATTER_FORWARD);
 66:   VecScatterEnd(scatter->scatter, x, z, ADD_VALUES, SCATTER_FORWARD);
 67:   return 0;
 68: }

 70: PetscErrorCode MatMultTranspose_Scatter(Mat A, Vec x, Vec y)
 71: {
 72:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 75:   VecZeroEntries(y);
 76:   VecScatterBegin(scatter->scatter, x, y, ADD_VALUES, SCATTER_REVERSE);
 77:   VecScatterEnd(scatter->scatter, x, y, ADD_VALUES, SCATTER_REVERSE);
 78:   return 0;
 79: }

 81: PetscErrorCode MatMultTransposeAdd_Scatter(Mat A, Vec x, Vec y, Vec z)
 82: {
 83:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 86:   if (z != y) VecCopy(y, z);
 87:   VecScatterBegin(scatter->scatter, x, z, ADD_VALUES, SCATTER_REVERSE);
 88:   VecScatterEnd(scatter->scatter, x, z, ADD_VALUES, SCATTER_REVERSE);
 89:   return 0;
 90: }

 92: static struct _MatOps MatOps_Values = {NULL,
 93:                                        NULL,
 94:                                        NULL,
 95:                                        MatMult_Scatter,
 96:                                        /*  4*/ MatMultAdd_Scatter,
 97:                                        MatMultTranspose_Scatter,
 98:                                        MatMultTransposeAdd_Scatter,
 99:                                        NULL,
100:                                        NULL,
101:                                        NULL,
102:                                        /* 10*/ NULL,
103:                                        NULL,
104:                                        NULL,
105:                                        NULL,
106:                                        NULL,
107:                                        /* 15*/ NULL,
108:                                        NULL,
109:                                        NULL,
110:                                        NULL,
111:                                        NULL,
112:                                        /* 20*/ NULL,
113:                                        NULL,
114:                                        NULL,
115:                                        NULL,
116:                                        /* 24*/ NULL,
117:                                        NULL,
118:                                        NULL,
119:                                        NULL,
120:                                        NULL,
121:                                        /* 29*/ NULL,
122:                                        NULL,
123:                                        NULL,
124:                                        NULL,
125:                                        NULL,
126:                                        /* 34*/ NULL,
127:                                        NULL,
128:                                        NULL,
129:                                        NULL,
130:                                        NULL,
131:                                        /* 39*/ NULL,
132:                                        NULL,
133:                                        NULL,
134:                                        NULL,
135:                                        NULL,
136:                                        /* 44*/ NULL,
137:                                        NULL,
138:                                        MatShift_Basic,
139:                                        NULL,
140:                                        NULL,
141:                                        /* 49*/ NULL,
142:                                        NULL,
143:                                        NULL,
144:                                        NULL,
145:                                        NULL,
146:                                        /* 54*/ NULL,
147:                                        NULL,
148:                                        NULL,
149:                                        NULL,
150:                                        NULL,
151:                                        /* 59*/ NULL,
152:                                        MatDestroy_Scatter,
153:                                        NULL,
154:                                        NULL,
155:                                        NULL,
156:                                        /* 64*/ NULL,
157:                                        NULL,
158:                                        NULL,
159:                                        NULL,
160:                                        NULL,
161:                                        /* 69*/ NULL,
162:                                        NULL,
163:                                        NULL,
164:                                        NULL,
165:                                        NULL,
166:                                        /* 74*/ NULL,
167:                                        NULL,
168:                                        NULL,
169:                                        NULL,
170:                                        NULL,
171:                                        /* 79*/ NULL,
172:                                        NULL,
173:                                        NULL,
174:                                        NULL,
175:                                        NULL,
176:                                        /* 84*/ NULL,
177:                                        NULL,
178:                                        NULL,
179:                                        NULL,
180:                                        NULL,
181:                                        /* 89*/ NULL,
182:                                        NULL,
183:                                        NULL,
184:                                        NULL,
185:                                        NULL,
186:                                        /* 94*/ NULL,
187:                                        NULL,
188:                                        NULL,
189:                                        NULL,
190:                                        NULL,
191:                                        /*99*/ NULL,
192:                                        NULL,
193:                                        NULL,
194:                                        NULL,
195:                                        NULL,
196:                                        /*104*/ NULL,
197:                                        NULL,
198:                                        NULL,
199:                                        NULL,
200:                                        NULL,
201:                                        /*109*/ NULL,
202:                                        NULL,
203:                                        NULL,
204:                                        NULL,
205:                                        NULL,
206:                                        /*114*/ NULL,
207:                                        NULL,
208:                                        NULL,
209:                                        NULL,
210:                                        NULL,
211:                                        /*119*/ NULL,
212:                                        NULL,
213:                                        NULL,
214:                                        NULL,
215:                                        NULL,
216:                                        /*124*/ NULL,
217:                                        NULL,
218:                                        NULL,
219:                                        NULL,
220:                                        NULL,
221:                                        /*129*/ NULL,
222:                                        NULL,
223:                                        NULL,
224:                                        NULL,
225:                                        NULL,
226:                                        /*134*/ NULL,
227:                                        NULL,
228:                                        NULL,
229:                                        NULL,
230:                                        NULL,
231:                                        /*139*/ NULL,
232:                                        NULL,
233:                                        NULL,
234:                                        NULL,
235:                                        NULL,
236:                                        /*144*/ NULL,
237:                                        NULL,
238:                                        NULL,
239:                                        NULL,
240:                                        NULL,
241:                                        NULL,
242:                                        /*150*/ NULL};

244: /*MC
245:    MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a `VecScatterBegin()` and `VecScatterEnd()`

247:   Level: advanced

249: .seealso: ``MATSCATTER`, MatCreateScatter()`, `MatScatterSetVecScatter()`, `MatScatterGetVecScatter()`
250: M*/

252: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
253: {
254:   Mat_Scatter *b;

256:   PetscMemcpy(A->ops, &MatOps_Values, sizeof(struct _MatOps));
257:   PetscNew(&b);

259:   A->data = (void *)b;

261:   PetscLayoutSetUp(A->rmap);
262:   PetscLayoutSetUp(A->cmap);

264:   A->assembled    = PETSC_TRUE;
265:   A->preallocated = PETSC_FALSE;

267:   PetscObjectChangeTypeName((PetscObject)A, MATSCATTER);
268:   return 0;
269: }

271: #include <petsc/private/sfimpl.h>
272: /*@C
273:    MatCreateScatter - Creates a new matrix of `MatType` `MATSCATTER`, based on a VecScatter

275:   Collective

277:    Input Parameters:
278: +  comm - MPI communicator
279: -  scatter - a `VecScatter`

281:    Output Parameter:
282: .  A - the matrix

284:    Level: intermediate

286:    PETSc requires that matrices and vectors being used for certain
287:    operations are partitioned accordingly.  For example, when
288:    creating a scatter matrix, A, that supports parallel matrix-vector
289:    products using `MatMult`(A,x,y) the user should set the number
290:    of local matrix rows to be the number of local elements of the
291:    corresponding result vector, y. Note that this is information is
292:    required for use of the matrix interface routines, even though
293:    the scatter matrix may not actually be physically partitioned.

295:   Developer Note:
296:    This directly accesses information inside the `VecScatter` associated with the matrix-vector product
297:    for this matrix. This is not desirable..

299: .seealso: `MatScatterSetVecScatter()`, `MatScatterGetVecScatter()`, `MATSCATTER`
300: @*/
301: PetscErrorCode MatCreateScatter(MPI_Comm comm, VecScatter scatter, Mat *A)
302: {
303:   MatCreate(comm, A);
304:   MatSetSizes(*A, scatter->vscat.to_n, scatter->vscat.from_n, PETSC_DETERMINE, PETSC_DETERMINE);
305:   MatSetType(*A, MATSCATTER);
306:   MatScatterSetVecScatter(*A, scatter);
307:   MatSetUp(*A);
308:   return 0;
309: }

311: /*@
312:     MatScatterSetVecScatter - sets the scatter that the matrix is to apply as its linear operator in a `MATSCATTER`

314:    Collective

316:     Input Parameters:
317: +   mat - the `MATSCATTER` matrix
318: -   scatter - the scatter context create with `VecScatterCreate()`

320:    Level: advanced

322: .seealso: `MATSCATTER`, `MatCreateScatter()`, `MATSCATTER`
323: @*/
324: PetscErrorCode MatScatterSetVecScatter(Mat mat, VecScatter scatter)
325: {
326:   Mat_Scatter *mscatter = (Mat_Scatter *)mat->data;


334:   PetscObjectReference((PetscObject)scatter);
335:   VecScatterDestroy(&mscatter->scatter);

337:   mscatter->scatter = scatter;
338:   return 0;
339: }