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