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