Actual source code: mscatter.c
petsc-3.7.1 2016-05-15
Report Typos and Errors

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