Actual source code: dmget.c

      1: #include <petsc/private/dmimpl.h>

      3: /*@
      4:    DMGetLocalVector - Gets a PETSc vector that may be used with the DM local routines. This vector has spaces for the ghost values.

      6:    Not Collective

      8:    Input Parameter:
      9: .  dm - the dm

     11:    Output Parameter:
     12: .  g - the local vector

     14:    Level: beginner

     16:    Note:
     17:    The vector values are NOT initialized and may have garbage in them, so you may need
     18:    to zero them.

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

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

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

     29: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
     30:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
     31:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector(),
     32:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
     33: @*/
     34: PetscErrorCode  DMGetLocalVector(DM dm,Vec *g)
     35: {
     38:   for (PetscInt i=0; i<DM_MAX_WORK_VECTORS; i++) {
     39:     if (dm->localin[i]) {
     40:       DM vdm;

     42:       *g             = dm->localin[i];
     43:       dm->localin[i] = NULL;

     45:       VecGetDM(*g,&vdm);
     47:       VecSetDM(*g,dm);
     48:       goto alldone;
     49:     }
     50:   }
     51:   DMCreateLocalVector(dm,g);

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

     63: /*@
     64:    DMRestoreLocalVector - Returns a PETSc vector that was
     65:      obtained from DMGetLocalVector(). Do not use with vector obtained via
     66:      DMCreateLocalVector().

     68:    Not Collective

     70:    Input Parameters:
     71: +  dm - the dm
     72: -  g - the local vector

     74:    Level: beginner

     76: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
     77:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
     78:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMGetLocalVector()
     79: @*/
     80: PetscErrorCode  DMRestoreLocalVector(DM dm,Vec *g)
     81: {
     82:   PetscInt       i,j;

     86:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
     87:     if (*g == dm->localout[j]) {
     88:       DM vdm;

     90:       VecGetDM(*g,&vdm);
     92:       VecSetDM(*g,NULL);
     93:       dm->localout[j] = NULL;
     94:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
     95:         if (!dm->localin[i]) {
     96:           dm->localin[i] = *g;
     97:           goto alldone;
     98:         }
     99:       }
    100:     }
    101:   }
    102:   VecDestroy(g);
    103: alldone:
    104:   *g = NULL;
    105:   return 0;
    106: }

    108: /*@
    109:    DMGetGlobalVector - Gets a PETSc vector that may be used with the DM global routines.

    111:    Collective on dm

    113:    Input Parameter:
    114: .  dm - the dm

    116:    Output Parameter:
    117: .  g - the global vector

    119:    Level: beginner

    121:    Note:
    122:    The vector values are NOT initialized and may have garbage in them, so you may need
    123:    to zero them.

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

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

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

    134: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    135:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    136:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    137:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    138: @*/
    139: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
    140: {
    141:   PetscInt       i;

    145:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    146:     if (dm->globalin[i]) {
    147:       DM vdm;

    149:       *g              = dm->globalin[i];
    150:       dm->globalin[i] = NULL;

    152:       VecGetDM(*g,&vdm);
    154:       VecSetDM(*g,dm);
    155:       goto alldone;
    156:     }
    157:   }
    158:   DMCreateGlobalVector(dm,g);

    160: alldone:
    161:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    162:     if (!dm->globalout[i]) {
    163:       dm->globalout[i] = *g;
    164:       break;
    165:     }
    166:   }
    167:   return 0;
    168: }

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

    173:    Collective on dm

    175:    Input Parameter:
    176: .  dm - the dm

    178:    Level: developer

    180: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    181:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    182:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    183:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    184: @*/
    185: PetscErrorCode  DMClearGlobalVectors(DM dm)
    186: {
    187:   PetscInt       i;

    190:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    191:     Vec g;

    194:     g = dm->globalin[i];
    195:     dm->globalin[i] = NULL;
    196:     if (g) {
    197:       DM vdm;

    199:       VecGetDM(g,&vdm);
    201:     }
    202:     VecDestroy(&g);
    203:   }
    204:   return 0;
    205: }

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

    210:    Collective on dm

    212:    Input Parameter:
    213: .  dm - the dm

    215:    Level: developer

    217: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
    218:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
    219:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    220:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    221: @*/
    222: PetscErrorCode  DMClearLocalVectors(DM dm)
    223: {
    224:   PetscInt       i;

    227:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    228:     Vec g;

    231:     g = dm->localin[i];
    232:     dm->localin[i] = NULL;
    233:     if (g) {
    234:       DM vdm;

    236:       VecGetDM(g,&vdm);
    238:     }
    239:     VecDestroy(&g);
    240:   }
    241:   return 0;
    242: }

    244: /*@
    245:    DMRestoreGlobalVector - Returns a PETSc vector that
    246:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
    247:      DMCreateGlobalVector().

    249:    Not Collective

    251:    Input Parameters:
    252: +  dm - the dm
    253: -  g - the global vector

    255:    Level: beginner

    257: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    258:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToGlobalBegin(),
    259:           DMGlobalToGlobalEnd(), DMGlobalToGlobal(), DMCreateLocalVector(), DMGetGlobalVector()
    260: @*/
    261: PetscErrorCode  DMRestoreGlobalVector(DM dm,Vec *g)
    262: {
    263:   PetscInt       i,j;

    267:   VecSetErrorIfLocked(*g, 2);
    268:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
    269:     if (*g == dm->globalout[j]) {
    270:       DM vdm;

    272:       VecGetDM(*g,&vdm);
    274:       VecSetDM(*g,NULL);
    275:       dm->globalout[j] = NULL;
    276:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    277:         if (!dm->globalin[i]) {
    278:           dm->globalin[i] = *g;
    279:           goto alldone;
    280:         }
    281:       }
    282:     }
    283:   }
    284:   VecDestroy(g);
    285: alldone:
    286:   *g = NULL;
    287:   return 0;
    288: }

    290: /*@C
    291:    DMHasNamedGlobalVector - check for a named, persistent global vector

    293:    Not Collective

    295:    Input Parameters:
    296: +  dm - DM to hold named vectors
    297: -  name - unique name for Vec

    299:    Output Parameter:
    300: .  exists - true if the vector was previously created

    302:    Level: developer

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

    306: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    307: @*/
    308: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
    309: {
    310:   DMNamedVecLink link;

    315:   *exists = PETSC_FALSE;
    316:   for (link=dm->namedglobal; link; link=link->next) {
    317:     PetscBool match;
    318:     PetscStrcmp(name,link->name,&match);
    319:     if (match) {
    320:       *exists = PETSC_TRUE;
    321:       break;
    322:     }
    323:   }
    324:   return 0;
    325: }

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

    330:    Collective on dm

    332:    Input Parameters:
    333: +  dm - DM to hold named vectors
    334: -  name - unique name for Vec

    336:    Output Parameter:
    337: .  X - named Vec

    339:    Level: developer

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

    343: .seealso: DMRestoreNamedGlobalVector()
    344: @*/
    345: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
    346: {
    347:   DMNamedVecLink link;

    352:   for (link=dm->namedglobal; link; link=link->next) {
    353:     PetscBool match;

    355:     PetscStrcmp(name,link->name,&match);
    356:     if (match) {
    357:       DM vdm;

    360:       VecGetDM(link->X,&vdm);
    362:       VecSetDM(link->X,dm);
    363:       goto found;
    364:     }
    365:   }

    367:   /* Create the Vec */
    368:   PetscNew(&link);
    369:   PetscStrallocpy(name,&link->name);
    370:   DMCreateGlobalVector(dm,&link->X);
    371:   link->next      = dm->namedglobal;
    372:   dm->namedglobal = link;

    374: found:
    375:   *X           = link->X;
    376:   link->status = DMVEC_STATUS_OUT;
    377:   return 0;
    378: }

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

    383:    Collective on dm

    385:    Input Parameters:
    386: +  dm - DM on which the vector was gotten
    387: .  name - name under which the vector was gotten
    388: -  X - Vec to restore

    390:    Level: developer

    392: .seealso: DMGetNamedGlobalVector()
    393: @*/
    394: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
    395: {
    396:   DMNamedVecLink link;

    402:   for (link=dm->namedglobal; link; link=link->next) {
    403:     PetscBool match;

    405:     PetscStrcmp(name,link->name,&match);
    406:     if (match) {
    407:       DM vdm;

    409:       VecGetDM(*X,&vdm);

    414:       link->status = DMVEC_STATUS_IN;
    415:       VecSetDM(link->X,NULL);
    416:       *X           = NULL;
    417:       return 0;
    418:     }
    419:   }
    420:   SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    421: }

    423: /*@C
    424:    DMHasNamedLocalVector - check for a named, persistent local vector

    426:    Not Collective

    428:    Input Parameters:
    429: +  dm - DM to hold named vectors
    430: -  name - unique name for Vec

    432:    Output Parameter:
    433: .  exists - true if the vector was previously created

    435:    Level: developer

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

    439: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    440: @*/
    441: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
    442: {
    443:   DMNamedVecLink link;

    448:   *exists = PETSC_FALSE;
    449:   for (link=dm->namedlocal; link; link=link->next) {
    450:     PetscBool match;
    451:     PetscStrcmp(name,link->name,&match);
    452:     if (match) {
    453:       *exists = PETSC_TRUE;
    454:       break;
    455:     }
    456:   }
    457:   return 0;
    458: }

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

    463:    Not Collective

    465:    Input Parameters:
    466: +  dm - DM to hold named vectors
    467: -  name - unique name for Vec

    469:    Output Parameter:
    470: .  X - named Vec

    472:    Level: developer

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

    476: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    477: @*/
    478: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
    479: {
    480:   DMNamedVecLink link;

    485:   for (link=dm->namedlocal; link; link=link->next) {
    486:     PetscBool match;

    488:     PetscStrcmp(name,link->name,&match);
    489:     if (match) {
    490:       DM vdm;

    493:       VecGetDM(link->X,&vdm);
    495:       VecSetDM(link->X,dm);
    496:       goto found;
    497:     }
    498:   }

    500:   /* Create the Vec */
    501:   PetscNew(&link);
    502:   PetscStrallocpy(name,&link->name);
    503:   DMCreateLocalVector(dm,&link->X);
    504:   link->next     = dm->namedlocal;
    505:   dm->namedlocal = link;

    507: found:
    508:   *X           = link->X;
    509:   link->status = DMVEC_STATUS_OUT;
    510:   return 0;
    511: }

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

    516:    Not Collective

    518:    Input Parameters:
    519: +  dm - DM on which the vector was gotten
    520: .  name - name under which the vector was gotten
    521: -  X - Vec to restore

    523:    Level: developer

    525: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
    526: @*/
    527: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
    528: {
    529:   DMNamedVecLink link;

    535:   for (link=dm->namedlocal; link; link=link->next) {
    536:     PetscBool match;

    538:     PetscStrcmp(name,link->name,&match);
    539:     if (match) {
    540:       DM vdm;

    542:       VecGetDM(*X,&vdm);

    547:       link->status = DMVEC_STATUS_IN;
    548:       VecSetDM(link->X,NULL);
    549:       *X           = NULL;
    550:       return 0;
    551:     }
    552:   }
    553:   SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    554: }