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;

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

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

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

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

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

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

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

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

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

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

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

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

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

    250:   Level: advanced

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

    254: M*/

    256: PETSC_EXTERN PetscErrorCode MatCreate_Scatter(Mat A)
    257: {
    258:   Mat_Scatter    *b;

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

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

    267:   PetscLayoutSetUp(A->rmap);
    268:   PetscLayoutSetUp(A->cmap);

    270:   A->assembled    = PETSC_TRUE;
    271:   A->preallocated = PETSC_FALSE;

    273:   PetscObjectChangeTypeName((PetscObject)A,MATSCATTER);
    274:   return(0);
    275: }

    277: #include <petsc/private/sfimpl.h>
    278: /*@C
    279:    MatCreateScatter - Creates a new matrix based on a VecScatter

    281:   Collective

    283:    Input Parameters:
    284: +  comm - MPI communicator
    285: -  scatter - a VecScatterContext

    287:    Output Parameter:
    288: .  A - the matrix

    290:    Level: intermediate

    292:    PETSc requires that matrices and vectors being used for certain
    293:    operations are partitioned accordingly.  For example, when
    294:    creating a scatter matrix, A, that supports parallel matrix-vector
    295:    products using MatMult(A,x,y) the user should set the number
    296:    of local matrix rows to be the number of local elements of the
    297:    corresponding result vector, y. Note that this is information is
    298:    required for use of the matrix interface routines, even though
    299:    the scatter matrix may not actually be physically partitioned.

    301:   Developer Notes: This directly accesses information inside the VecScatter associated with the matrix-vector product
    302:    for this matrix. This is not desirable..

    305: .seealso: MatScatterSetVecScatter(), MatScatterGetVecScatter(), MATSCATTER
    306: @*/
    307: PetscErrorCode  MatCreateScatter(MPI_Comm comm,VecScatter scatter,Mat *A)
    308: {

    312:   MatCreate(comm,A);
    313:   MatSetSizes(*A,scatter->vscat.to_n,scatter->vscat.from_n,PETSC_DETERMINE,PETSC_DETERMINE);
    314:   MatSetType(*A,MATSCATTER);
    315:   MatScatterSetVecScatter(*A,scatter);
    316:   MatSetUp(*A);
    317:   return(0);
    318: }

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

    323:    Collective on Mat

    325:     Input Parameters:
    326: +   mat - the scatter matrix
    327: -   scatter - the scatter context create with VecScatterCreate()

    329:    Level: advanced

    332: .seealso: MatCreateScatter(), MATSCATTER
    333: @*/
    334: PetscErrorCode  MatScatterSetVecScatter(Mat mat,VecScatter scatter)
    335: {
    336:   Mat_Scatter    *mscatter = (Mat_Scatter*)mat->data;

    343:   if (mat->rmap->n != scatter->vscat.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->vscat.to_n);
    344:   if (mat->cmap->n != scatter->vscat.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->vscat.from_n);

    346:   PetscObjectReference((PetscObject)scatter);
    347:   VecScatterDestroy(&mscatter->scatter);

    349:   mscatter->scatter = scatter;
    350:   return(0);
    351: }