Actual source code: mscatter.c
petsc-3.7.3 2016-08-01
2: /*
3: This provides a matrix that applies a VecScatter to a vector.
4: */
6: #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/
7: #include <petsc/private/vecimpl.h>
9: typedef struct {
10: VecScatter scatter;
11: } Mat_Scatter;
15: /*@
16: MatScatterGetVecScatter - Returns the user-provided scatter set with MatScatterSetVecScatter()
18: Not Collective, but not cannot use scatter if not used collectively on Mat
20: Input Parameter:
21: . mat - the matrix, should have been created with MatCreateScatter() or have type MATSCATTER
23: Output Parameter:
24: . scatter - the scatter context
26: Level: intermediate
28: .keywords: matrix, scatter, get
30: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER
31: @*/
32: PetscErrorCode MatScatterGetVecScatter(Mat mat,VecScatter *scatter)
33: {
34: Mat_Scatter *mscatter;
39: mscatter = (Mat_Scatter*)mat->data;
40: *scatter = mscatter->scatter;
41: return(0);
42: }
46: PetscErrorCode MatDestroy_Scatter(Mat mat)
47: {
49: Mat_Scatter *scatter = (Mat_Scatter*)mat->data;
52: VecScatterDestroy(&scatter->scatter);
53: PetscFree(mat->data);
54: return(0);
55: }
59: PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y)
60: {
61: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
65: if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
66: VecZeroEntries(y);
67: VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
68: VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
69: return(0);
70: }
74: PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
75: {
76: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
80: if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
81: if (z != y) {VecCopy(y,z);}
82: VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
83: VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
84: return(0);
85: }
89: PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y)
90: {
91: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
95: if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
96: VecZeroEntries(y);
97: VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
98: VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
99: return(0);
100: }
104: PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
105: {
106: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
110: if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
111: if (z != y) {VecCopy(y,z);}
112: VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
113: VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
114: return(0);
115: }
117: static struct _MatOps MatOps_Values = {0,
118: 0,
119: 0,
120: MatMult_Scatter,
121: /* 4*/ MatMultAdd_Scatter,
122: MatMultTranspose_Scatter,
123: MatMultTransposeAdd_Scatter,
124: 0,
125: 0,
126: 0,
127: /* 10*/ 0,
128: 0,
129: 0,
130: 0,
131: 0,
132: /* 15*/ 0,
133: 0,
134: 0,
135: 0,
136: 0,
137: /* 20*/ 0,
138: 0,
139: 0,
140: 0,
141: /* 24*/ 0,
142: 0,
143: 0,
144: 0,
145: 0,
146: /* 29*/ 0,
147: 0,
148: 0,
149: 0,
150: 0,
151: /* 34*/ 0,
152: 0,
153: 0,
154: 0,
155: 0,
156: /* 39*/ 0,
157: 0,
158: 0,
159: 0,
160: 0,
161: /* 44*/ 0,
162: 0,
163: MatShift_Basic,
164: 0,
165: 0,
166: /* 49*/ 0,
167: 0,
168: 0,
169: 0,
170: 0,
171: /* 54*/ 0,
172: 0,
173: 0,
174: 0,
175: 0,
176: /* 59*/ 0,
177: MatDestroy_Scatter,
178: 0,
179: 0,
180: 0,
181: /* 64*/ 0,
182: 0,
183: 0,
184: 0,
185: 0,
186: /* 69*/ 0,
187: 0,
188: 0,
189: 0,
190: 0,
191: /* 74*/ 0,
192: 0,
193: 0,
194: 0,
195: 0,
196: /* 79*/ 0,
197: 0,
198: 0,
199: 0,
200: 0,
201: /* 84*/ 0,
202: 0,
203: 0,
204: 0,
205: 0,
206: /* 89*/ 0,
207: 0,
208: 0,
209: 0,
210: 0,
211: /* 94*/ 0,
212: 0,
213: 0,
214: 0,
215: 0,
216: /*99*/ 0,
217: 0,
218: 0,
219: 0,
220: 0,
221: /*104*/ 0,
222: 0,
223: 0,
224: 0,
225: 0,
226: /*109*/ 0,
227: 0,
228: 0,
229: 0,
230: 0,
231: /*114*/ 0,
232: 0,
233: 0,
234: 0,
235: 0,
236: /*119*/ 0,
237: 0,
238: 0,
239: 0,
240: 0,
241: /*124*/ 0,
242: 0,
243: 0,
244: 0,
245: 0,
246: /*129*/ 0,
247: 0,
248: 0,
249: 0,
250: 0,
251: /*134*/ 0,
252: 0,
253: 0,
254: 0,
255: 0,
256: /*139*/ 0,
257: 0,
258: 0
259: };
261: /*MC
262: MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()
264: Level: advanced
266: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()
268: M*/
272: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
273: {
274: Mat_Scatter *b;
278: PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));
279: PetscNewLog(A,&b);
281: A->data = (void*)b;
283: PetscLayoutSetUp(A->rmap);
284: PetscLayoutSetUp(A->cmap);
286: A->assembled = PETSC_TRUE;
287: A->preallocated = PETSC_FALSE;
289: PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);
290: return(0);
291: }
295: /*@C
296: MatCreateScatter - Creates a new matrix based on a VecScatter
298: Collective on MPI_Comm
300: Input Parameters:
301: + comm - MPI communicator
302: - scatter - a VecScatterContext
304: Output Parameter:
305: . A - the matrix
307: Level: intermediate
309: PETSc requires that matrices and vectors being used for certain
310: operations are partitioned accordingly. For example, when
311: creating a scatter matrix, A, that supports parallel matrix-vector
312: products using MatMult(A,x,y) the user should set the number
313: of local matrix rows to be the number of local elements of the
314: corresponding result vector, y. Note that this is information is
315: required for use of the matrix interface routines, even though
316: the scatter matrix may not actually be physically partitioned.
318: .keywords: matrix, scatter, create
320: .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
321: @*/
322: PetscErrorCode MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
323: {
327: MatCreate(comm,A);
328: MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);
329: MatSetType(*A,MATSCATTER);
330: MatScatterSetVecScatter(*A,scatter);
331: MatSetUp(*A);
332: return(0);
333: }
337: /*@
338: MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator
340: Collective on Mat
342: Input Parameters:
343: + mat - the scatter matrix
344: - scatter - the scatter context create with VecScatterCreate()
346: Level: advanced
349: .seealso: MatCreateScatter(), MATSCATTER
350: @*/
351: PetscErrorCode MatScatterSetVecScatter(Mat mat,VecScatter scatter)
352: {
353: Mat_Scatter *mscatter = (Mat_Scatter*)mat->data;
360: if (mat->rmap->n != scatter->to_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local rows in matrix %D not equal local scatter size %D",mat->rmap->n,scatter->to_n);
361: if (mat->cmap->n != scatter->from_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Number of local columns in matrix %D not equal local scatter size %D",mat->cmap->n,scatter->from_n);
363: PetscObjectReference((PetscObject)scatter);
364: VecScatterDestroy(&mscatter->scatter);
366: mscatter->scatter = scatter;
367: return(0);
368: }