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

      1: #include <petsc/private/dmimpl.h> /*I "petscdm.h" I*/

      5: /*@
      6:    DMGetLocalVector - Gets a Seq PETSc vector that
      7:    may be used with the DMXXX routines. This vector has spaces for the ghost values.

      9:    Not Collective

     11:    Input Parameter:
     12: .  dm - the distributed array

     14:    Output Parameter:
     15: .  g - the local vector

     17:    Level: beginner

     19:    Note:
     20:    The vector values are NOT initialized and may have garbage in them, so you may need
     21:    to zero them.

     23:    The output parameter, g, is a regular PETSc vector that should be returned with
     24:    DMRestoreLocalVector() DO NOT call VecDestroy() on it.

     26:    This is intended to be used for vectors you need for a short time, like within a single function call.
     27:    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
     28:    code you should use DMCreateLocalVector().

     30:    VecStride*() operations can be useful when using DM with dof > 1

     32: .keywords: distributed array, create, local, vector

     34: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
     35:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
     36:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
     37:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
     38: @*/
     39: PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
     40: {
     41:   PetscErrorCode ierr,i;

     46:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
     47:     if (dm->localin[i]) {
     48:       *g             = dm->localin[i];
     49:       dm->localin[i] = NULL;
     50:       goto alldone;
     51:     }
     52:   }
     53:   DMCreateLocalVector(dm,g);

     55: alldone:
     56:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
     57:     if (!dm->localout[i]) {
     58:       dm->localout[i] = *g;
     59:       break;
     60:     }
     61:   }
     62:   return(0);
     63: }

     67: /*@
     68:    DMRestoreLocalVector - Returns a Seq PETSc vector that
     69:      obtained from DMGetLocalVector(). Do not use with vector obtained via
     70:      DMCreateLocalVector().

     72:    Not Collective

     74:    Input Parameter:
     75: +  dm - the distributed array
     76: -  g - the local vector

     78:    Level: beginner

     80: .keywords: distributed array, create, local, vector

     82: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
     83:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
     84:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
     85: @*/
     86: PetscErrorCode  DMRestoreLocalVector(DM dm,Vec *g)
     87: {
     89:   PetscInt       i,j;

     94:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
     95:     if (*g == dm->localout[j]) {
     96:       dm->localout[j] = NULL;
     97:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
     98:         if (!dm->localin[i]) {
     99:           dm->localin[i] = *g;
    100:           goto alldone;
    101:         }
    102:       }
    103:     }
    104:   }
    105:   VecDestroy(g);
    106: alldone:
    107:   *g = NULL;
    108:   return(0);
    109: }

    113: /*@
    114:    DMGetGlobalVector - Gets a MPI PETSc vector that
    115:    may be used with the DMXXX routines.

    117:    Collective on DM

    119:    Input Parameter:
    120: .  dm - the distributed array

    122:    Output Parameter:
    123: .  g - the global vector

    125:    Level: beginner

    127:    Note:
    128:    The vector values are NOT initialized and may have garbage in them, so you may need
    129:    to zero them.

    131:    The output parameter, g, is a regular PETSc vector that should be returned with
    132:    DMRestoreGlobalVector() DO NOT call VecDestroy() on it.

    134:    This is intended to be used for vectors you need for a short time, like within a single function call.
    135:    For vectors that you intend to keep around (for example in a C struct) or pass around large parts of your
    136:    code you should use DMCreateGlobalVector().

    138:    VecStride*() operations can be useful when using DM with dof > 1

    140: .keywords: distributed array, create, Global, vector

    142: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    143:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    144:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    145:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    147: @*/
    148: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
    149: {
    151:   PetscInt       i;

    156:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    157:     if (dm->globalin[i]) {
    158:       *g              = dm->globalin[i];
    159:       dm->globalin[i] = NULL;
    160:       goto alldone;
    161:     }
    162:   }
    163:   DMCreateGlobalVector(dm,g);

    165: alldone:
    166:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    167:     if (!dm->globalout[i]) {
    168:       dm->globalout[i] = *g;
    169:       break;
    170:     }
    171:   }
    172:   return(0);
    173: }

    177: /*@
    178:    DMClearGlobalVectors - Destroys all the global vectors that have been stashed in this DM

    180:    Collective on DM

    182:    Input Parameter:
    183: .  dm - the distributed array

    185:    Level: developer

    187: .keywords: distributed array, create, Global, vector

    189: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    190:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    191:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    192:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    194: @*/
    195: PetscErrorCode  DMClearGlobalVectors(DM dm)
    196: {
    198:   PetscInt       i;

    202:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    203:     Vec g;
    204:     if (dm->globalout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
    205:     g = dm->globalin[i];
    206:     dm->globalin[i] = NULL;
    207:     VecDestroy(&g);
    208:   }
    209:   return(0);
    210: }

    214: /*@
    215:    DMClearLocalVectors - Destroys all the local vectors that have been stashed in this DM

    217:    Collective on DM

    219:    Input Parameter:
    220: .  dm - the distributed array

    222:    Level: developer

    224: .keywords: distributed array, create, Local, vector

    226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
    227:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
    228:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    229:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    231: @*/
    232: PetscErrorCode  DMClearLocalVectors(DM dm)
    233: {
    235:   PetscInt       i;

    239:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    240:     Vec g;
    241:     if (dm->localout[i]) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of local vectors that has a local vector obtained with DMGetLocalVector()");
    242:     g = dm->localin[i];
    243:     dm->localin[i] = NULL;
    244:     VecDestroy(&g);
    245:   }
    246:   return(0);
    247: }

    251: /*@
    252:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
    253:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
    254:      DMCreateGlobalVector().

    256:    Not Collective

    258:    Input Parameter:
    259: +  dm - the distributed array
    260: -  g - the global vector

    262:    Level: beginner

    264: .keywords: distributed array, create, global, vector

    266: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    267:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
    268:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
    269: @*/
    270: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
    271: {
    273:   PetscInt       i,j;

    278:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
    279:     if (*g == dm->globalout[j]) {
    280:       dm->globalout[j] = NULL;
    281:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    282:         if (!dm->globalin[i]) {
    283:           dm->globalin[i] = *g;
    284:           goto alldone;
    285:         }
    286:       }
    287:     }
    288:   }
    289:   VecDestroy(g);
    290: alldone:
    291:   *g = NULL;
    292:   return(0);
    293: }

    297: /*@C
    298:    DMHasNamedGlobalVector - check for a named, persistent global vector

    300:    Not Collective

    302:    Input Arguments:
    303: +  dm - DM to hold named vectors
    304: -  name - unique name for Vec

    306:    Output Arguments:
    307: .  exists - true if the vector was previously created

    309:    Level: developer

    311:    Note: If a Vec with the given name does not exist, it is created.

    313: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    314: @*/
    315: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
    316: {
    318:   DMNamedVecLink link;

    324:   *exists = PETSC_FALSE;
    325:   for (link=dm->namedglobal; link; link=link->next) {
    326:     PetscBool match;
    327:     PetscStrcmp(name,link->name,&match);
    328:     if (match) {
    329:       *exists = PETSC_TRUE;
    330:       break;
    331:     }
    332:   }
    333:   return(0);
    334: }

    338: /*@C
    339:    DMGetNamedGlobalVector - get access to a named, persistent global vector

    341:    Collective on DM

    343:    Input Arguments:
    344: +  dm - DM to hold named vectors
    345: -  name - unique name for Vec

    347:    Output Arguments:
    348: .  X - named Vec

    350:    Level: developer

    352:    Note: If a Vec with the given name does not exist, it is created.

    354: .seealso: DMRestoreNamedGlobalVector()
    355: @*/
    356: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
    357: {
    359:   DMNamedVecLink link;

    365:   for (link=dm->namedglobal; link; link=link->next) {
    366:     PetscBool match;
    367:     PetscStrcmp(name,link->name,&match);
    368:     if (match) {
    369:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    370:       goto found;
    371:     }
    372:   }

    374:   /* Create the Vec */
    375:   PetscNew(&link);
    376:   PetscStrallocpy(name,&link->name);
    377:   DMCreateGlobalVector(dm,&link->X);
    378:   link->next      = dm->namedglobal;
    379:   dm->namedglobal = link;

    381: found:
    382:   *X           = link->X;
    383:   link->status = DMVEC_STATUS_OUT;
    384:   return(0);
    385: }

    389: /*@C
    390:    DMRestoreNamedGlobalVector - restore access to a named, persistent global vector

    392:    Collective on DM

    394:    Input Arguments:
    395: +  dm - DM on which the vector was gotten
    396: .  name - name under which the vector was gotten
    397: -  X - Vec to restore

    399:    Output Arguments:

    401:    Level: developer

    403: .seealso: DMGetNamedGlobalVector()
    404: @*/
    405: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
    406: {
    408:   DMNamedVecLink link;

    415:   for (link=dm->namedglobal; link; link=link->next) {
    416:     PetscBool match;
    417:     PetscStrcmp(name,link->name,&match);
    418:     if (match) {
    419:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    420:       if (link->X != *X) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
    421:       link->status = DMVEC_STATUS_IN;
    422:       *X           = NULL;
    423:       return(0);
    424:     }
    425:   }
    426:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    427:   return(0);
    428: }

    432: /*@C
    433:    DMHasNamedLocalVector - check for a named, persistent local vector

    435:    Not Collective

    437:    Input Arguments:
    438: +  dm - DM to hold named vectors
    439: -  name - unique name for Vec

    441:    Output Arguments:
    442: .  exists - true if the vector was previously created

    444:    Level: developer

    446:    Note: If a Vec with the given name does not exist, it is created.

    448: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    449: @*/
    450: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
    451: {
    453:   DMNamedVecLink link;

    459:   *exists = PETSC_FALSE;
    460:   for (link=dm->namedlocal; link; link=link->next) {
    461:     PetscBool match;
    462:     PetscStrcmp(name,link->name,&match);
    463:     if (match) {
    464:       *exists = PETSC_TRUE;
    465:       break;
    466:     }
    467:   }
    468:   return(0);
    469: }

    473: /*@C
    474:    DMGetNamedLocalVector - get access to a named, persistent local vector

    476:    Not Collective

    478:    Input Arguments:
    479: +  dm - DM to hold named vectors
    480: -  name - unique name for Vec

    482:    Output Arguments:
    483: .  X - named Vec

    485:    Level: developer

    487:    Note: If a Vec with the given name does not exist, it is created.

    489: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    490: @*/
    491: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
    492: {
    494:   DMNamedVecLink link;

    500:   for (link=dm->namedlocal; link; link=link->next) {
    501:     PetscBool match;
    502:     PetscStrcmp(name,link->name,&match);
    503:     if (match) {
    504:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    505:       goto found;
    506:     }
    507:   }

    509:   /* Create the Vec */
    510:   PetscNew(&link);
    511:   PetscStrallocpy(name,&link->name);
    512:   DMCreateLocalVector(dm,&link->X);
    513:   link->next     = dm->namedlocal;
    514:   dm->namedlocal = link;

    516: found:
    517:   *X           = link->X;
    518:   link->status = DMVEC_STATUS_OUT;
    519:   return(0);
    520: }

    524: /*@C
    525:    DMRestoreNamedLocalVector - restore access to a named, persistent local vector

    527:    Not Collective

    529:    Input Arguments:
    530: +  dm - DM on which the vector was gotten
    531: .  name - name under which the vector was gotten
    532: -  X - Vec to restore

    534:    Output Arguments:

    536:    Level: developer

    538: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
    539: @*/
    540: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
    541: {
    543:   DMNamedVecLink link;

    550:   for (link=dm->namedlocal; link; link=link->next) {
    551:     PetscBool match;
    552:     PetscStrcmp(name,link->name,&match);
    553:     if (match) {
    554:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    555:       if (link->X != *X) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Attempt to restore Vec name '%s', but Vec does not match the cache",name);
    556:       link->status = DMVEC_STATUS_IN;
    557:       *X           = NULL;
    558:       return(0);
    559:     }
    560:   }
    561:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    562:   return(0);
    563: }