Actual source code: mscatter.c

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

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

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

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

 15:   Logically Collective

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

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

 23:   Level: intermediate

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

 31:   PetscFunctionBegin;
 33:   PetscAssertPointer(scatter, 2);
 34:   mscatter = (Mat_Scatter *)mat->data;
 35:   *scatter = mscatter->scatter;
 36:   PetscFunctionReturn(PETSC_SUCCESS);
 37: }

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

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

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

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

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

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

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

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

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

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

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

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

257:   Level: advanced

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

262: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
263: {
264:   Mat_Scatter *b;

266:   PetscFunctionBegin;
267:   A->ops[0] = MatOps_Values;
268:   PetscCall(PetscNew(&b));

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

272:   PetscCall(PetscLayoutSetUp(A->rmap));
273:   PetscCall(PetscLayoutSetUp(A->cmap));

275:   A->assembled    = PETSC_TRUE;
276:   A->preallocated = PETSC_FALSE;

278:   PetscCall(PetscObjectChangeTypeName((PetscObject)A, MATSCATTER));
279:   PetscFunctionReturn(PETSC_SUCCESS);
280: }

282: #include <petsc/private/sfimpl.h>
283: /*@
284:   MatCreateScatter - Creates a new matrix of `MatType` `MATSCATTER`, based on a VecScatter

286:   Collective

288:   Input Parameters:
289: + comm    - MPI communicator
290: - scatter - a `VecScatter`

292:   Output Parameter:
293: . A - the matrix

295:   Level: intermediate

297:   Notes:
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.

307:   Developer Notes:
308:   This directly accesses information inside the `VecScatter` associated with the matrix-vector product
309:   for this matrix. This is not desirable..

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

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

327:   Logically Collective

329:   Input Parameters:
330: + mat     - the `MATSCATTER` matrix
331: - scatter - the scatter context create with `VecScatterCreate()`

333:   Level: advanced

335: .seealso: [](ch_matrices), `Mat`, `MATSCATTER`, `MatCreateScatter()`
336: @*/
337: PetscErrorCode MatScatterSetVecScatter(Mat mat, VecScatter scatter)
338: {
339:   Mat_Scatter *mscatter = (Mat_Scatter *)mat->data;

341:   PetscFunctionBegin;
344:   PetscCheckSameComm((PetscObject)scatter, 2, (PetscObject)mat, 1);
345:   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);
346:   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);

348:   PetscCall(PetscObjectReference((PetscObject)scatter));
349:   PetscCall(VecScatterDestroy(&mscatter->scatter));

351:   mscatter->scatter = scatter;
352:   PetscFunctionReturn(PETSC_SUCCESS);
353: }