Actual source code: vecmpitoseq.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

      2:  #include <petsc/private/vecimpl.h>

      4: /*@C
      5:       VecScatterCreateToAll - Creates a vector and a scatter context that copies all
      6:           vector values to each processor

      8:   Collective on Vec

     10:   Input Parameter:
     11: .  vin  - input MPIVEC

     13:   Output Parameter:
     14: +  ctx - scatter context
     15: -  vout - output SEQVEC that is large enough to scatter into

     17:   Level: intermediate

     19:    Note: vout may be NULL [PETSC_NULL_VEC from fortran] if you do not
     20:    need to have it created

     22:    Usage:
     23: $        VecScatterCreateToAll(vin,&ctx,&vout);
     24: $
     25: $        // scatter as many times as you need
     26: $        VecScatterBegin(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD);
     27: $        VecScatterEnd(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD);
     28: $
     29: $        // destroy scatter context and local vector when no longer needed
     30: $        VecScatterDestroy(&ctx);
     31: $        VecDestroy(&vout);

     33:     Do NOT create a vector and then pass it in as the final argument vout! vout is created by this routine
     34:   automatically (unless you pass NULL in for that argument if you do not need it).

     36: .seealso VecScatterCreate(), VecScatterCreateToZero(), VecScatterBegin(), VecScatterEnd()

     38: @*/
     39: PetscErrorCode  VecScatterCreateToAll(Vec vin,VecScatter *ctx,Vec *vout)
     40: {

     43:   PetscInt       N;
     44:   IS             is;
     45:   Vec            tmp;
     46:   Vec            *tmpv;
     47:   PetscBool      tmpvout = PETSC_FALSE;

     53:   if (vout) {
     55:     tmpv = vout;
     56:   } else {
     57:     tmpvout = PETSC_TRUE;
     58:     tmpv    = &tmp;
     59:   }

     61:   /* Create seq vec on each proc, with the same size of the original mpi vec */
     62:   VecGetSize(vin,&N);
     63:   VecCreateSeq(PETSC_COMM_SELF,N,tmpv);
     64:   /* Create the VecScatter ctx with the communication info */
     65:   ISCreateStride(PETSC_COMM_SELF,N,0,1,&is);
     66:   VecScatterCreate(vin,is,*tmpv,is,ctx);
     67:   ISDestroy(&is);
     68:   if (tmpvout) {VecDestroy(tmpv);}
     69:   return(0);
     70: }

     73: /*@C
     74:       VecScatterCreateToZero - Creates an output vector and a scatter context used to
     75:               copy all vector values into the output vector on the zeroth processor

     77:   Collective on Vec

     79:   Input Parameter:
     80: .  vin  - input MPIVEC

     82:   Output Parameter:
     83: +  ctx - scatter context
     84: -  vout - output SEQVEC that is large enough to scatter into on processor 0 and
     85:           of length zero on all other processors

     87:   Level: intermediate

     89:    Note: vout may be NULL [PETSC_NULL_VEC from fortran] if you do not
     90:    need to have it created

     92:    Usage:
     93: $        VecScatterCreateToZero(vin,&ctx,&vout);
     94: $
     95: $        // scatter as many times as you need
     96: $        VecScatterBegin(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD);
     97: $        VecScatterEnd(ctx,vin,vout,INSERT_VALUES,SCATTER_FORWARD);
     98: $
     99: $        // destroy scatter context and local vector when no longer needed
    100: $        VecScatterDestroy(&ctx);
    101: $        VecDestroy(&vout);

    103: .seealso VecScatterCreate(), VecScatterCreateToAll(), VecScatterBegin(), VecScatterEnd()

    105:     Do NOT create a vector and then pass it in as the final argument vout! vout is created by this routine
    106:   automatically (unless you pass NULL in for that argument if you do not need it).

    108: @*/
    109: PetscErrorCode  VecScatterCreateToZero(Vec vin,VecScatter *ctx,Vec *vout)
    110: {

    113:   PetscInt       N;
    114:   PetscMPIInt    rank;
    115:   IS             is;
    116:   Vec            tmp;
    117:   Vec            *tmpv;
    118:   PetscBool      tmpvout = PETSC_FALSE;

    124:   if (vout) {
    126:     tmpv = vout;
    127:   } else {
    128:     tmpvout = PETSC_TRUE;
    129:     tmpv    = &tmp;
    130:   }

    132:   /* Create vec on each proc, with the same size of the original mpi vec (all on process 0)*/
    133:   VecGetSize(vin,&N);
    134:   MPI_Comm_rank(PetscObjectComm((PetscObject)vin),&rank);
    135:   if (rank) N = 0;
    136:   VecCreateSeq(PETSC_COMM_SELF,N,tmpv);
    137:   /* Create the VecScatter ctx with the communication info */
    138:   ISCreateStride(PETSC_COMM_SELF,N,0,1,&is);
    139:   VecScatterCreate(vin,is,*tmpv,is,ctx);
    140:   ISDestroy(&is);
    141:   if (tmpvout) {VecDestroy(tmpv);}
    142:   return(0);
    143: }

    145:  #include <petscsf.h>

    147: /*@
    148:   PetscSFCreateFromZero - Create a PetscSF that maps a Vec from sequential to distributed

    150:   Input Parameters:
    151: . gv - A distributed Vec

    153:   Output Parameters:
    154: . sf - The SF created mapping a sequential Vec to gv

    156:   Level: developer

    158: .seealso: DMPlexDistributedToSequential()
    159: @*/
    160: PetscErrorCode PetscSFCreateFromZero(MPI_Comm comm, Vec gv, PetscSF *sf)
    161: {
    162:   PetscSFNode   *remotenodes;
    163:   PetscInt      *localnodes;
    164:   PetscInt       N, n, start, numroots, l;
    165:   PetscMPIInt    rank;

    169:   PetscSFCreate(comm, sf);
    170:   VecGetSize(gv, &N);
    171:   VecGetLocalSize(gv, &n);
    172:   VecGetOwnershipRange(gv, &start, NULL);
    173:   MPI_Comm_rank(comm, &rank);
    174:   PetscMalloc1(n, &localnodes);
    175:   PetscMalloc1(n, &remotenodes);
    176:   if (!rank) numroots = N;
    177:   else       numroots = 0;
    178:   for (l = 0; l < n; ++l) {
    179:     localnodes[l]        = l;
    180:     remotenodes[l].rank  = 0;
    181:     remotenodes[l].index = l+start;
    182:   }
    183:   PetscSFSetGraph(*sf, numroots, n, localnodes, PETSC_OWN_POINTER, remotenodes, PETSC_OWN_POINTER);
    184:   return(0);
    185: }