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()
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: 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: };
242: /*MC
243: MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()
245: Level: advanced
247: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()
249: M*/
251: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
252: {
253: Mat_Scatter *b;
255: PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));
256: PetscNewLog(A,&b);
258: A->data = (void*)b;
260: PetscLayoutSetUp(A->rmap);
261: PetscLayoutSetUp(A->cmap);
263: A->assembled = PETSC_TRUE;
264: A->preallocated = PETSC_FALSE;
266: PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);
267: return 0;
268: }
270: #include <petsc/private/sfimpl.h>
271: /*@C
272: MatCreateScatter - Creates a new matrix based on a VecScatter
274: Collective
276: Input Parameters:
277: + comm - MPI communicator
278: - scatter - a VecScatterContext
280: Output Parameter:
281: . A - the matrix
283: Level: intermediate
285: PETSc requires that matrices and vectors being used for certain
286: operations are partitioned accordingly. For example, when
287: creating a scatter matrix, A, that supports parallel matrix-vector
288: products using MatMult(A,x,y) the user should set the number
289: of local matrix rows to be the number of local elements of the
290: corresponding result vector, y. Note that this is information is
291: required for use of the matrix interface routines, even though
292: the scatter matrix may not actually be physically partitioned.
294: Developer Notes: This directly accesses information inside the VecScatter associated with the matrix-vector product
295: for this matrix. This is not desirable..
297: .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
298: @*/
299: PetscErrorCode MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
300: {
301: MatCreate(comm,A);
302: MatSetSizes(*A,scatter->vscat.to_n,scatter->vscat.from_n,PETSC_DETERMINE,PETSC_DETERMINE);
303: MatSetType(*A,MATSCATTER);
304: MatScatterSetVecScatter(*A,scatter);
305: MatSetUp(*A);
306: return 0;
307: }
309: /*@
310: MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator
312: Collective on Mat
314: Input Parameters:
315: + mat - the scatter matrix
316: - scatter - the scatter context create with VecScatterCreate()
318: Level: advanced
320: .seealso: MatCreateScatter(), MATSCATTER
321: @*/
322: PetscErrorCode MatScatterSetVecScatter(Mat mat,VecScatter scatter)
323: {
324: Mat_Scatter *mscatter = (Mat_Scatter*)mat->data;
332: PetscObjectReference((PetscObject)scatter);
333: VecScatterDestroy(&mscatter->scatter);
335: mscatter->scatter = scatter;
336: return 0;
337: }