Actual source code: mscatter.c

petsc-3.10.5 2019-03-28
Report Typos and Errors

  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: .keywords: matrix, scatter, get

 28: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MATSCATTER
 29: @*/
 30: PetscErrorCode  MatScatterGetVecScatter(Mat mat,VecScatter *scatter)
 31: {
 32:   Mat_Scatter *mscatter;

 37:   mscatter = (Mat_Scatter*)mat->data;
 38:   *scatter = mscatter->scatter;
 39:   return(0);
 40: }

 42: PetscErrorCode MatDestroy_Scatter(Mat mat)
 43: {
 45:   Mat_Scatter    *scatter = (Mat_Scatter*)mat->data;

 48:   VecScatterDestroy(&scatter->scatter);
 49:   PetscFree(mat->data);
 50:   return(0);
 51: }

 53: PetscErrorCode MatMult_Scatter(Mat A,Vec x,Vec y)
 54: {
 55:   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;

 59:   if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
 60:   VecZeroEntries(y);
 61:   VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
 62:   VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_FORWARD);
 63:   return(0);
 64: }

 66: PetscErrorCode MatMultAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
 67: {
 68:   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;

 72:   if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
 73:   if (z != y) {VecCopy(y,z);}
 74:   VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
 75:   VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_FORWARD);
 76:   return(0);
 77: }

 79: PetscErrorCode MatMultTranspose_Scatter(Mat A,Vec x,Vec y)
 80: {
 81:   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;

 85:   if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
 86:   VecZeroEntries(y);
 87:   VecScatterBegin(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
 88:   VecScatterEnd(scatter->scatter,x,y,ADD_VALUES,SCATTER_REVERSE);
 89:   return(0);
 90: }

 92: PetscErrorCode MatMultTransposeAdd_Scatter(Mat A,Vec x,Vec y,Vec z)
 93: {
 94:   Mat_Scatter    *scatter = (Mat_Scatter*)A->data;

 98:   if (!scatter->scatter) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONGSTATE,"Need to first call MatScatterSetScatter()");
 99:   if (z != y) {VecCopy(y,z);}
100:   VecScatterBegin(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
101:   VecScatterEnd(scatter->scatter,x,z,ADD_VALUES,SCATTER_REVERSE);
102:   return(0);
103: }

105: static struct _MatOps MatOps_Values = {0,
106:                                        0,
107:                                        0,
108:                                        MatMult_Scatter,
109:                                /*  4*/ MatMultAdd_Scatter,
110:                                        MatMultTranspose_Scatter,
111:                                        MatMultTransposeAdd_Scatter,
112:                                        0,
113:                                        0,
114:                                        0,
115:                                /* 10*/ 0,
116:                                        0,
117:                                        0,
118:                                        0,
119:                                        0,
120:                                /* 15*/ 0,
121:                                        0,
122:                                        0,
123:                                        0,
124:                                        0,
125:                                /* 20*/ 0,
126:                                        0,
127:                                        0,
128:                                        0,
129:                                /* 24*/ 0,
130:                                        0,
131:                                        0,
132:                                        0,
133:                                        0,
134:                                /* 29*/ 0,
135:                                        0,
136:                                        0,
137:                                        0,
138:                                        0,
139:                                /* 34*/ 0,
140:                                        0,
141:                                        0,
142:                                        0,
143:                                        0,
144:                                /* 39*/ 0,
145:                                        0,
146:                                        0,
147:                                        0,
148:                                        0,
149:                                /* 44*/ 0,
150:                                        0,
151:                                        MatShift_Basic,
152:                                        0,
153:                                        0,
154:                                /* 49*/ 0,
155:                                        0,
156:                                        0,
157:                                        0,
158:                                        0,
159:                                /* 54*/ 0,
160:                                        0,
161:                                        0,
162:                                        0,
163:                                        0,
164:                                /* 59*/ 0,
165:                                        MatDestroy_Scatter,
166:                                        0,
167:                                        0,
168:                                        0,
169:                                /* 64*/ 0,
170:                                        0,
171:                                        0,
172:                                        0,
173:                                        0,
174:                                /* 69*/ 0,
175:                                        0,
176:                                        0,
177:                                        0,
178:                                        0,
179:                                /* 74*/ 0,
180:                                        0,
181:                                        0,
182:                                        0,
183:                                        0,
184:                                /* 79*/ 0,
185:                                        0,
186:                                        0,
187:                                        0,
188:                                        0,
189:                                /* 84*/ 0,
190:                                        0,
191:                                        0,
192:                                        0,
193:                                        0,
194:                                /* 89*/ 0,
195:                                        0,
196:                                        0,
197:                                        0,
198:                                        0,
199:                                /* 94*/ 0,
200:                                        0,
201:                                        0,
202:                                        0,
203:                                        0,
204:                                 /*99*/ 0,
205:                                        0,
206:                                        0,
207:                                        0,
208:                                        0,
209:                                /*104*/ 0,
210:                                        0,
211:                                        0,
212:                                        0,
213:                                        0,
214:                                /*109*/ 0,
215:                                        0,
216:                                        0,
217:                                        0,
218:                                        0,
219:                                /*114*/ 0,
220:                                        0,
221:                                        0,
222:                                        0,
223:                                        0,
224:                                /*119*/ 0,
225:                                        0,
226:                                        0,
227:                                        0,
228:                                        0,
229:                                /*124*/ 0,
230:                                        0,
231:                                        0,
232:                                        0,
233:                                        0,
234:                                /*129*/ 0,
235:                                        0,
236:                                        0,
237:                                        0,
238:                                        0,
239:                                /*134*/ 0,
240:                                        0,
241:                                        0,
242:                                        0,
243:                                        0,
244:                                /*139*/ 0,
245:                                        0,
246:                                        0
247: };

249: /*MC
250:    MATSCATTER - MATSCATTER = "scatter" - A matrix type that simply applies a VecScatterBegin/End()

252:   Level: advanced

254: .seealso: MatCreateScatter(), MatScatterSetVecScatter(), MatScatterGetVecScatter()

256: M*/

258: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
259: {
260:   Mat_Scatter    *b;

264:   PetscMemcpy(A->ops,&MatOps_Values,sizeof(struct _MatOps));
265:   PetscNewLog(A,&b);

267:   A->data = (void*)b;

269:   PetscLayoutSetUp(A->rmap);
270:   PetscLayoutSetUp(A->cmap);

272:   A->assembled    = PETSC_TRUE;
273:   A->preallocated = PETSC_FALSE;

275:   PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);
276:   return(0);
277: }

279:  #include <petsc/private/vecscatterimpl.h>
280: /*@C
281:    MatCreateScatter - Creates a new matrix based on a VecScatter

283:   Collective on MPI_Comm

285:    Input Parameters:
286: +  comm - MPI communicator
287: -  scatter - a VecScatterContext

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 Notes: This directly accesses information inside the VecScatter associated with the matrix-vector product
304:    for this matrix. This is not desirable..


307: .keywords: matrix, scatter, create

309: .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
310: @*/
311: PetscErrorCode  MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
312: {

316:   MatCreate(comm,A);
317:   MatSetSizes(*A,scatter->to_n,scatter->from_n,PETSC_DETERMINE,PETSC_DETERMINE);
318:   MatSetType(*A,MATSCATTER);
319:   MatScatterSetVecScatter(*A,scatter);
320:   MatSetUp(*A);
321:   return(0);
322: }

324: /*@
325:     MatScatterSetVecScatter - sets that scatter that the matrix is to apply as its linear operator

327:    Collective on Mat

329:     Input Parameters:
330: +   mat - the scatter matrix
331: -   scatter - the scatter context create with VecScatterCreate()

333:    Level: advanced


336: .seealso: MatCreateScatter(), MATSCATTER
337: @*/
338: PetscErrorCode  MatScatterSetVecScatter(Mat mat,VecScatter scatter)
339: {
340:   Mat_Scatter    *mscatter = (Mat_Scatter*)mat->data;

347:   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);
348:   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);

350:   PetscObjectReference((PetscObject)scatter);
351:   VecScatterDestroy(&mscatter->scatter);

353:   mscatter->scatter = scatter;
354:   return(0);
355: }