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:     Logically Collective

 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: [](ch_matrices), `Mat`, `MATSCATTER`, `MatCreateScatter()`, `MatScatterSetVecScatter()`, `MATSCATTER`
 27: @*/
 28: PetscErrorCode MatScatterGetVecScatter(Mat mat, VecScatter *scatter)
 29: {
 30:   Mat_Scatter *mscatter;

 32:   PetscFunctionBegin;
 35:   mscatter = (Mat_Scatter *)mat->data;
 36:   *scatter = mscatter->scatter;
 37:   PetscFunctionReturn(PETSC_SUCCESS);
 38: }

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

 44:   PetscFunctionBegin;
 45:   PetscCall(VecScatterDestroy(&scatter->scatter));
 46:   PetscCall(PetscFree(mat->data));
 47:   PetscFunctionReturn(PETSC_SUCCESS);
 48: }

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

 54:   PetscFunctionBegin;
 55:   PetscCheck(scatter->scatter, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Need to first call MatScatterSetScatter()");
 56:   PetscCall(VecZeroEntries(y));
 57:   PetscCall(VecScatterBegin(scatter->scatter, x, y, ADD_VALUES, SCATTER_FORWARD));
 58:   PetscCall(VecScatterEnd(scatter->scatter, x, y, ADD_VALUES, SCATTER_FORWARD));
 59:   PetscFunctionReturn(PETSC_SUCCESS);
 60: }

 62: PetscErrorCode MatMultAdd_Scatter(Mat A, Vec x, Vec y, Vec z)
 63: {
 64:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 66:   PetscFunctionBegin;
 67:   PetscCheck(scatter->scatter, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Need to first call MatScatterSetScatter()");
 68:   if (z != y) PetscCall(VecCopy(y, z));
 69:   PetscCall(VecScatterBegin(scatter->scatter, x, z, ADD_VALUES, SCATTER_FORWARD));
 70:   PetscCall(VecScatterEnd(scatter->scatter, x, z, ADD_VALUES, SCATTER_FORWARD));
 71:   PetscFunctionReturn(PETSC_SUCCESS);
 72: }

 74: PetscErrorCode MatMultTranspose_Scatter(Mat A, Vec x, Vec y)
 75: {
 76:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 78:   PetscFunctionBegin;
 79:   PetscCheck(scatter->scatter, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Need to first call MatScatterSetScatter()");
 80:   PetscCall(VecZeroEntries(y));
 81:   PetscCall(VecScatterBegin(scatter->scatter, x, y, ADD_VALUES, SCATTER_REVERSE));
 82:   PetscCall(VecScatterEnd(scatter->scatter, x, y, ADD_VALUES, SCATTER_REVERSE));
 83:   PetscFunctionReturn(PETSC_SUCCESS);
 84: }

 86: PetscErrorCode MatMultTransposeAdd_Scatter(Mat A, Vec x, Vec y, Vec z)
 87: {
 88:   Mat_Scatter *scatter = (Mat_Scatter *)A->data;

 90:   PetscFunctionBegin;
 91:   PetscCheck(scatter->scatter, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONGSTATE, "Need to first call MatScatterSetScatter()");
 92:   if (z != y) PetscCall(VecCopy(y, z));
 93:   PetscCall(VecScatterBegin(scatter->scatter, x, z, ADD_VALUES, SCATTER_REVERSE));
 94:   PetscCall(VecScatterEnd(scatter->scatter, x, z, ADD_VALUES, SCATTER_REVERSE));
 95:   PetscFunctionReturn(PETSC_SUCCESS);
 96: }

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

251: /*MC
252:    MATSCATTER - "scatter" - A matrix type that simply applies a `VecScatterBegin()` and `VecScatterEnd()` to perform `MatMult()`

254:   Level: advanced

256: .seealso: [](ch_matrices), `Mat`, ``MATSCATTER`, MatCreateScatter()`, `MatScatterSetVecScatter()`, `MatScatterGetVecScatter()`
257: M*/

259: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
260: {
261:   Mat_Scatter *b;

263:   PetscFunctionBegin;
264:   PetscCall(PetscMemcpy(A->ops, &MatOps_Values, sizeof(struct _MatOps)));
265:   PetscCall(PetscNew(&b));

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

269:   PetscCall(PetscLayoutSetUp(A->rmap));
270:   PetscCall(PetscLayoutSetUp(A->cmap));

272:   A->assembled    = PETSC_TRUE;
273:   A->preallocated = PETSC_FALSE;

275:   PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATSCATTER));
276:   PetscFunctionReturn(PETSC_SUCCESS);
277: }

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

283:   Collective

285:    Input Parameters:
286: +  comm - MPI communicator
287: -  scatter - a `VecScatter`

289:    Output Parameter:
290: .  A - the matrix

292:    Level: intermediate

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.

303:   Developer Note:
304:    This directly accesses information inside the `VecScatter` associated with the matrix-vector product
305:    for this matrix. This is not desirable..

307: .seealso: [](ch_matrices), `Mat`, `MatScatterSetVecScatter()`, `MatScatterGetVecScatter()`, `MATSCATTER`
308: @*/
309: PetscErrorCode MatCreateScatter(MPI_Comm comm, VecScatter scatter, Mat *A)
310: {
311:   PetscFunctionBegin;
312:   PetscCall(MatCreate(comm, A));
313:   PetscCall(MatSetSizes(*A, scatter->vscat.to_n, scatter->vscat.from_n, PETSC_DETERMINE, PETSC_DETERMINE));
314:   PetscCall(MatSetType(*A, MATSCATTER));
315:   PetscCall(MatScatterSetVecScatter(*A, scatter));
316:   PetscCall(MatSetUp(*A));
317:   PetscFunctionReturn(PETSC_SUCCESS);
318: }

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

323:    Logically Collective

325:     Input Parameters:
326: +   mat - the `MATSCATTER` matrix
327: -   scatter - the scatter context create with `VecScatterCreate()`

329:    Level: advanced

331: .seealso: [](ch_matrices), `Mat`, `MATSCATTER`, `MatCreateScatter()`, `MATSCATTER`
332: @*/
333: PetscErrorCode MatScatterSetVecScatter(Mat mat, VecScatter scatter)
334: {
335:   Mat_Scatter *mscatter = (Mat_Scatter *)mat->data;

337:   PetscFunctionBegin;
340:   PetscCheckSameComm((PetscObject)scatter, 2, (PetscObject)mat, 1);
341:   PetscCheck(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);
342:   PetscCheck(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);

344:   PetscCall(PetscObjectReference((PetscObject)scatter));
345:   PetscCall(VecScatterDestroy(&mscatter->scatter));

347:   mscatter->scatter = scatter;
348:   PetscFunctionReturn(PETSC_SUCCESS);
349: }