Actual source code: mscatter.c
1: #define PETSCMAT_DLL
3: /*
4: This provides a matrix that applies a VecScatter to a vector.
5: */
7: #include private/matimpl.h
8: #include private/vecimpl.h
10: typedef struct {
11: VecScatter scatter;
12: } Mat_Scatter;
16: /*@
17: MatScatterGetVecScatter - Returns the user-provided scatter set with MatScatterSetVecScatter()
19: Not Collective, but not cannot use scatter if not used collectively on Mat
21: Input Parameter:
22: . mat - the matrix, should have been created with MatCreateScatter() or have type MATSCATTER
24: Output Parameter:
25: . scatter - the scatter context
27: Level: intermediate
29: .keywords: matrix, scatter, get
31: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER
32: @*/
33: PetscErrorCode MatScatterGetVecScatter(Mat mat,VecScatter *scatter)
34: {
35: Mat_Scatter *mscatter;
40: mscatter = (Mat_Scatter*)mat->data;
41: *scatter = mscatter->scatter;
42: return(0);
43: }
47: PetscErrorCode MatDestroy_Scatter(Mat mat)
48: {
50: Mat_Scatter *scatter = (Mat_Scatter*)mat->data;
53: if (scatter->scatter) {VecScatterDestroy(scatter->scatter);}
54: PetscFree(scatter);
55: return(0);
56: }
60: PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y)
61: {
62: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
66: if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
67: VecZeroEntries(y);
68: VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
69: VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
70: return(0);
71: }
75: PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
76: {
77: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
81: if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
82: if (z != y) {VecCopy(y,z);}
83: VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
84: VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
85: return(0);
86: }
90: PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y)
91: {
92: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
96: if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
97: VecZeroEntries(y);
98: VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
99: VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
100: return(0);
101: }
105: PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
106: {
107: Mat_Scatter *scatter = (Mat_Scatter*)A->data;
111: if (!scatter->scatter) SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
112: if (z != y) {VecCopy(y,z);}
113: VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
114: VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
115: return(0);
116: }
118: static struct _MatOps MatOps_Values = {0,
119: 0,
120: 0,
121: MatMult_Scatter,
122: /* 4*/ MatMultAdd_Scatter,
123: MatMultTranspose_Scatter,
124: MatMultTransposeAdd_Scatter,
125: 0,
126: 0,
127: 0,
128: /*10*/ 0,
129: 0,
130: 0,
131: 0,
132: 0,
133: /*15*/ 0,
134: 0,
135: 0,
136: 0,
137: 0,
138: /*20*/ 0,
139: 0,
140: 0,
141: 0,
142: /*24*/ 0,
143: 0,
144: 0,
145: 0,
146: 0,
147: /*29*/ 0,
148: 0,
149: 0,
150: 0,
151: 0,
152: /*34*/ 0,
153: 0,
154: 0,
155: 0,
156: 0,
157: /*39*/ 0,
158: 0,
159: 0,
160: 0,
161: 0,
162: /*44*/ 0,
163: 0,
164: 0,
165: 0,
166: 0,
167: /*49*/ 0,
168: 0,
169: 0,
170: 0,
171: 0,
172: /*54*/ 0,
173: 0,
174: 0,
175: 0,
176: 0,
177: /*59*/ 0,
178: MatDestroy_Scatter,
179: 0,
180: 0,
181: 0,
182: /*64*/ 0,
183: 0,
184: 0,
185: 0,
186: 0,
187: /*69*/ 0,
188: 0,
189: 0,
190: 0,
191: 0,
192: /*74*/ 0,
193: 0,
194: 0,
195: 0,
196: 0,
197: /*79*/ 0,
198: 0,
199: 0,
200: 0,
201: 0,
202: /*84*/ 0,
203: 0,
204: 0,
205: 0,
206: 0,
207: /*89*/ 0,
208: 0,
209: 0,
210: 0,
211: 0,
212: /*94*/ 0,
213: 0,
214: 0,
215: 0};
217: /*MC
218: MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()
220: Level: advanced
222: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()
224: M*/
229: PetscErrorCode MatCreate_Scatter(Mat A)
230: {
231: Mat_Scatter *b;
235: PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));
236: PetscNewLog(A,Mat_Scatter,&b);
238: A->data = (void*)b;
240: PetscLayoutSetBlockSize(A->rmap,1);
241: PetscLayoutSetBlockSize(A->cmap,1);
242: PetscLayoutSetUp(A->rmap);
243: PetscLayoutSetUp(A->cmap);
245: A->assembled = PETSC_TRUE;
246: A->preallocated = PETSC_FALSE;
248: PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);
249: return(0);
250: }
255: /*@C
256: MatCreateScatter - Creates a new matrix based on a VecScatter
258: Collective on MPI_Comm
260: Input Parameters:
261: + comm - MPI communicator
262: - scatter - a VecScatterContext
264: Output Parameter:
265: . A - the matrix
267: Level: intermediate
269: PETSc requires that matrices and vectors being used for certain
270: operations are partitioned accordingly. For example, when
271: creating a scatter matrix, A, that supports parallel matrix-vector
272: products using MatMult(A,x,y) the user should set the number
273: of local matrix rows to be the number of local elements of the
274: corresponding result vector, y. Note that this is information is
275: required for use of the matrix interface routines, even though
276: the scatter matrix may not actually be physically partitioned.
277: For example,
279: .keywords: matrix, scatter, create
281: .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
282: @*/
283: PetscErrorCode MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
284: {
288: MatCreate(comm,A);
289: MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);
290: MatSetType(*A,MATSCATTER);
291: MatScatterSetVecScatter(*A,scatter);
292: return(0);
293: }
297: /*@
298: MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator
300: Collective on Mat
302: Input Parameters:
303: + mat - the scatter matrix
304: - scatter - the scatter context create with VecScatterCreate()
306: Level: advanced
309: .seealso: MatCreateScatter(), MATSCATTER
310: @*/
311: PetscErrorCode MatScatterSetVecScatter(Mat mat,VecScatter scatter)
312: {
313: Mat_Scatter *mscatter = (Mat_Scatter*)mat->data;
320: if (mat->rmap->n != scatter->to_n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Number of local rows in matrix %D not equal local scatter size %D",mat->rmap->n,scatter->to_n);
321: if (mat->cmap->n != scatter->from_n) SETERRQ2(PETSC_ERR_ARG_SIZ,"Number of local columns in matrix %D not equal local scatter size %D",mat->cmap->n,scatter->from_n);
323: PetscObjectReference((PetscObject)scatter);
324: if (mscatter->scatter) {VecScatterDestroy(mscatter->scatter);}
325: mscatter->scatter = scatter;
326: return(0);
327: }