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: }