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