Date: 2013-07-02T14:40:08+00:00

Actual source code: commonmpvec.c
petsc-3.4.2 2013-07-02

      2: #include <../src/vec/vec/impls/mpi/pvecimpl.h>   /*I  "petscvec.h"   I*/

      6: /*
      7:   This is used in VecGhostGetLocalForm and VecGhostRestoreLocalForm to ensure
      8:   that the state is updated if either vector has changed since the last time
      9:   one of these functions was called.  It could apply to any PetscObject, but
     10:   VecGhost is quite different from other objects in that two separate vectors
     11:   look at the same memory.

     13:   In principle, we could only propagate state to the local vector on
     14:   GetLocalForm and to the global vector on RestoreLocalForm, but this version is
     15:   more conservative (i.e. robust against misuse) and simpler.

     17:   Note that this function is correct and changes nothing if both arguments are the
     18:   same, which is the case in serial.
     19: */
     20: static PetscErrorCode VecGhostStateSync_Private(Vec g,Vec l)
     21: {
     23:   PetscInt       gstate,lstate;

     26:   PetscObjectStateQuery((PetscObject)g,&gstate);
     27:   PetscObjectStateQuery((PetscObject)l,&lstate);
     28:   PetscObjectSetState((PetscObject)g,PetscMax(gstate,lstate));
     29:   PetscObjectSetState((PetscObject)l,PetscMax(gstate,lstate));
     30:   return(0);
     31: }

     36: /*@
     37:     VecGhostGetLocalForm - Obtains the local ghosted representation of
     38:     a parallel vector (obtained with VecCreateGhost(), VecCreateGhostWithArray()
     39:     or VecCreateSeq()). Returns NULL if the Vec is not ghosted.

     41:     Logically Collective

     43:     Input Parameter:
     44: .   g - the global vector

     46:     Output Parameter:
     47: .   l - the local (ghosted) representation, NULL if g is not ghosted

     49:     Notes:
     50:     This routine does not actually update the ghost values, but rather it
     51:     returns a sequential vector that includes the locations for the ghost
     52:     values and their current values. The returned vector and the original
     53:     vector passed in share the same array that contains the actual vector data.

     55:     To update the ghost values from the locations on the other processes one must call
     56:     VecGhostUpdateBegin() and VecGhostUpdateEnd() before accessing the ghost values. Thus normal
     57:     usage is
     58: $     VecGhostUpdateBegin(x,INSERT_VALUES,SCATTER_FORWARD);
     59: $     VecGhostUpdateEnd(x,INSERT_VALUES,SCATTER_FORWARD);
     60: $     VecGhostGetLocalForm(x,&xlocal);
     61: $     VecGetArray(xlocal,&xvalues);
     62: $        // access the non-ghost values in locations xvalues[0:n-1] and ghost values in locations xvalues[n:n+nghost];
     63: $     VecRestoreArray(xlocal,&xvalues);
     64: $     VecGhostRestoreLocalForm(x,&xlocal);

     66:     One should call VecGhostRestoreLocalForm() or VecDestroy() once one is
     67:     finished using the object.

     69:     Level: advanced

     71:    Concepts: vectors^ghost point access

     73: .seealso: VecCreateGhost(), VecGhostRestoreLocalForm(), VecCreateGhostWithArray()

     75: @*/
     76: PetscErrorCode  VecGhostGetLocalForm(Vec g,Vec *l)
     77: {
     79:   PetscBool      isseq,ismpi;

     85:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
     86:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
     87:   if (ismpi) {
     88:     Vec_MPI *v = (Vec_MPI*)g->data;
     89:     *l = v->localrep;
     90:   } else if (isseq) {
     91:     *l = g;
     92:   } else {
     93:     *l = NULL;
     94:   }
     95:   if (*l) {
     96:     VecGhostStateSync_Private(g,*l);
     97:     PetscObjectReference((PetscObject)*l);
     98:   }
     99:   return(0);
    100: }

    104: /*@
    105:     VecGhostIsLocalForm - Checks if a given vector is the local form of a global vector

    107:     Not Collective

    109:     Input Parameter:
    110: +   g - the global vector
    111: -   l - the local vector

    113:     Output Parameter:
    114: .   flg - PETSC_TRUE if local vector is local form

    116:     Level: advanced

    118:    Concepts: vectors^ghost point access

    120: .seealso: VecCreateGhost(), VecGhostRestoreLocalForm(), VecCreateGhostWithArray(), VecGhostGetLocalForm()

    122: @*/
    123: PetscErrorCode VecGhostIsLocalForm(Vec g,Vec l,PetscBool *flg)
    124: {
    126:   PetscBool      isseq,ismpi;

    132:   *flg = PETSC_FALSE;
    133:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
    134:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
    135:   if (ismpi) {
    136:     Vec_MPI *v = (Vec_MPI*)g->data;
    137:     if (l == v->localrep) *flg = PETSC_TRUE;
    138:   } else if (isseq) {
    139:     if (l == g) *flg = PETSC_TRUE;
    140:   } else SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Global vector is not ghosted");
    141:   return(0);
    142: }

    146: /*@
    147:     VecGhostRestoreLocalForm - Restores the local ghosted representation of
    148:     a parallel vector obtained with VecGhostGetLocalForm().

    150:     Logically Collective

    152:     Input Parameter:
    153: +   g - the global vector
    154: -   l - the local (ghosted) representation

    156:     Notes:
    157:     This routine does not actually update the ghost values, but rather it
    158:     returns a sequential vector that includes the locations for the ghost values
    159:     and their current values.

    161:     Level: advanced

    163: .seealso: VecCreateGhost(), VecGhostGetLocalForm(), VecCreateGhostWithArray()
    164: @*/
    165: PetscErrorCode  VecGhostRestoreLocalForm(Vec g,Vec *l)
    166: {

    170:   if (*l) {
    171:     VecGhostStateSync_Private(g,*l);
    172:     PetscObjectDereference((PetscObject)*l);
    173:   }
    174:   return(0);
    175: }

    179: /*@
    180:    VecGhostUpdateBegin - Begins the vector scatter to update the vector from
    181:    local representation to global or global representation to local.

    183:    Neighbor-wise Collective on Vec

    185:    Input Parameters:
    186: +  g - the vector (obtained with VecCreateGhost() or VecDuplicate())
    187: .  insertmode - one of ADD_VALUES or INSERT_VALUES
    188: -  scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE

    190:    Notes:
    191:    Use the following to update the ghost regions with correct values from the owning process
    192: .vb
    193:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
    194:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
    195: .ve

    197:    Use the following to accumulate the ghost region values onto the owning processors
    198: .vb
    199:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
    200:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
    201: .ve

    203:    To accumulate the ghost region values onto the owning processors and then update
    204:    the ghost regions correctly, call the later followed by the former, i.e.,
    205: .vb
    206:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
    207:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
    208:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
    209:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
    210: .ve

    212:    Level: advanced

    214: .seealso: VecCreateGhost(), VecGhostUpdateEnd(), VecGhostGetLocalForm(),
    215:           VecGhostRestoreLocalForm(),VecCreateGhostWithArray()

    217: @*/
    218: PetscErrorCode  VecGhostUpdateBegin(Vec g,InsertMode insertmode,ScatterMode scattermode)
    219: {
    220:   Vec_MPI        *v;
    222:   PetscBool      ismpi,isseq;

    226:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
    227:   PetscObjectTypeCompare((PetscObject)g,VECSEQ,&isseq);
    228:   if (ismpi) {
    229:     v = (Vec_MPI*)g->data;
    230:     if (!v->localrep) SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
    231:     if (!v->localupdate) return(0);
    232:     if (scattermode == SCATTER_REVERSE) {
    233:       VecScatterBegin(v->localupdate,v->localrep,g,insertmode,scattermode);
    234:     } else {
    235:       VecScatterBegin(v->localupdate,g,v->localrep,insertmode,scattermode);
    236:     }
    237:   } else if (isseq) {
    238:     /* Do nothing */
    239:   } else SETERRQ(PetscObjectComm((PetscObject)g),PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
    240:   return(0);
    241: }

    245: /*@
    246:    VecGhostUpdateEnd - End the vector scatter to update the vector from
    247:    local representation to global or global representation to local.

    249:    Neighbor-wise Collective on Vec

    251:    Input Parameters:
    252: +  g - the vector (obtained with VecCreateGhost() or VecDuplicate())
    253: .  insertmode - one of ADD_VALUES or INSERT_VALUES
    254: -  scattermode - one of SCATTER_FORWARD or SCATTER_REVERSE

    256:    Notes:

    258:    Use the following to update the ghost regions with correct values from the owning process
    259: .vb
    260:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
    261:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
    262: .ve

    264:    Use the following to accumulate the ghost region values onto the owning processors
    265: .vb
    266:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
    267:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
    268: .ve

    270:    To accumulate the ghost region values onto the owning processors and then update
    271:    the ghost regions correctly, call the later followed by the former, i.e.,
    272: .vb
    273:        VecGhostUpdateBegin(v,ADD_VALUES,SCATTER_REVERSE);
    274:        VecGhostUpdateEnd(v,ADD_VALUES,SCATTER_REVERSE);
    275:        VecGhostUpdateBegin(v,INSERT_VALUES,SCATTER_FORWARD);
    276:        VecGhostUpdateEnd(v,INSERT_VALUES,SCATTER_FORWARD);
    277: .ve

    279:    Level: advanced

    281: .seealso: VecCreateGhost(), VecGhostUpdateBegin(), VecGhostGetLocalForm(),
    282:           VecGhostRestoreLocalForm(),VecCreateGhostWithArray()

    284: @*/
    285: PetscErrorCode  VecGhostUpdateEnd(Vec g,InsertMode insertmode,ScatterMode scattermode)
    286: {
    287:   Vec_MPI        *v;
    289:   PetscBool      ismpi;

    293:   PetscObjectTypeCompare((PetscObject)g,VECMPI,&ismpi);
    294:   if (ismpi) {
    295:     v = (Vec_MPI*)g->data;
    296:     if (!v->localrep) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Vector is not ghosted");
    297:     if (!v->localupdate) return(0);
    298:     if (scattermode == SCATTER_REVERSE) {
    299:       VecScatterEnd(v->localupdate,v->localrep,g,insertmode,scattermode);
    300:     } else {
    301:       VecScatterEnd(v->localupdate,g,v->localrep,insertmode,scattermode);
    302:     }
    303:   }
    304:   return(0);
    305: }

    309: PetscErrorCode VecSetOption_MPI(Vec v,VecOption op,PetscBool flag)
    310: {
    312:   if (op == VEC_IGNORE_OFF_PROC_ENTRIES)      v->stash.donotstash   = flag;
    313:   else if (op == VEC_IGNORE_NEGATIVE_INDICES) v->stash.ignorenegidx = flag;
    314:   return(0);
    315: }

    320: PetscErrorCode VecResetArray_MPI(Vec vin)
    321: {
    322:   Vec_MPI        *v = (Vec_MPI*)vin->data;

    326:   v->array         = v->unplacedarray;
    327:   v->unplacedarray = 0;
    328:   if (v->localrep) {
    329:     VecResetArray(v->localrep);
    330:   }
    331:   return(0);
    332: }