Actual source code: dmget.c
petsc-3.13.6 2020-09-29
Report Typos and Errors

      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: {
     36:   PetscErrorCode ierr,i;

     41:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
     42:     if (dm->localin[i]) {
     43:       DM vdm;

     45:       *g             = dm->localin[i];
     46:       dm->localin[i] = NULL;

     48:       VecGetDM(*g,&vdm);
     49:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
     50:       VecSetDM(*g,dm);
     51:       goto alldone;
     52:     }
     53:   }
     54:   DMCreateLocalVector(dm,g);

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

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

     71:    Not Collective

     73:    Input Parameter:
     74: +  dm - the dm
     75: -  g - the local vector

     77:    Level: beginner

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

     91:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
     92:     if (*g == dm->localout[j]) {
     93:       DM vdm;

     95:       VecGetDM(*g,&vdm);
     96:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
     97:       VecSetDM(*g,NULL);
     98:       dm->localout[j] = NULL;
     99:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    100:         if (!dm->localin[i]) {
    101:           dm->localin[i] = *g;
    102:           goto alldone;
    103:         }
    104:       }
    105:     }
    106:   }
    107:   VecDestroy(g);
    108: alldone:
    109:   *g = NULL;
    110:   return(0);
    111: }

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

    116:    Collective on dm

    118:    Input Parameter:
    119: .  dm - the dm

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

    124:    Level: beginner

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

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

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

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

    139: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    140:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    141:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    142:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    143: @*/
    144: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
    145: {
    147:   PetscInt       i;

    152:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    153:     if (dm->globalin[i]) {
    154:       DM vdm;

    156:       *g              = dm->globalin[i];
    157:       dm->globalin[i] = NULL;

    159:       VecGetDM(*g,&vdm);
    160:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
    161:       VecSetDM(*g,dm);
    162:       goto alldone;
    163:     }
    164:   }
    165:   DMCreateGlobalVector(dm,g);

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

    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 dm

    185:    Level: developer

    187: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    188:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    189:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    190:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    191: @*/
    192: PetscErrorCode  DMClearGlobalVectors(DM dm)
    193: {
    195:   PetscInt       i;

    199:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    200:     Vec g;

    202:     if (dm->globalout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing DM of global vectors that has a global vector obtained with DMGetGlobalVector()");
    203:     g = dm->globalin[i];
    204:     dm->globalin[i] = NULL;
    205:     if (g) {
    206:       DM vdm;

    208:       VecGetDM(g,&vdm);
    209:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing global vector that has a DM attached");
    210:     }
    211:     VecDestroy(&g);
    212:   }
    213:   return(0);
    214: }

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

    219:    Collective on dm

    221:    Input Parameter:
    222: .  dm - the dm

    224:    Level: developer

    226: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
    227:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
    228:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    229:           VecStrideMax(), VecStrideMin(), VecStrideNorm()
    230: @*/
    231: PetscErrorCode  DMClearLocalVectors(DM dm)
    232: {
    234:   PetscInt       i;

    238:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    239:     Vec g;

    241:     if (dm->localout[i]) SETERRQ(PetscObjectComm((PetscObject)dm),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:     if (g) {
    245:       DM vdm;

    247:       VecGetDM(g,&vdm);
    248:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Clearing local vector that has a DM attached");
    249:     }
    250:     VecDestroy(&g);
    251:   }
    252:   return(0);
    253: }

    255: /*@
    256:    DMRestoreGlobalVector - Returns a PETSc vector that
    257:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
    258:      DMCreateGlobalVector().

    260:    Not Collective

    262:    Input Parameter:
    263: +  dm - the dm
    264: -  g - the global vector

    266:    Level: beginner

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

    280:   VecSetErrorIfLocked(*g, 2);
    281:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
    282:     if (*g == dm->globalout[j]) {
    283:       DM vdm;

    285:       VecGetDM(*g,&vdm);
    286:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");
    287:       VecSetDM(*g,NULL);
    288:       dm->globalout[j] = NULL;
    289:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    290:         if (!dm->globalin[i]) {
    291:           dm->globalin[i] = *g;
    292:           goto alldone;
    293:         }
    294:       }
    295:     }
    296:   }
    297:   VecDestroy(g);
    298: alldone:
    299:   *g = NULL;
    300:   return(0);
    301: }

    303: /*@C
    304:    DMHasNamedGlobalVector - check for a named, persistent global vector

    306:    Not Collective

    308:    Input Arguments:
    309: +  dm - DM to hold named vectors
    310: -  name - unique name for Vec

    312:    Output Arguments:
    313: .  exists - true if the vector was previously created

    315:    Level: developer

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

    319: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    320: @*/
    321: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
    322: {
    324:   DMNamedVecLink link;

    330:   *exists = PETSC_FALSE;
    331:   for (link=dm->namedglobal; link; link=link->next) {
    332:     PetscBool match;
    333:     PetscStrcmp(name,link->name,&match);
    334:     if (match) {
    335:       *exists = PETSC_TRUE;
    336:       break;
    337:     }
    338:   }
    339:   return(0);
    340: }

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

    345:    Collective on dm

    347:    Input Arguments:
    348: +  dm - DM to hold named vectors
    349: -  name - unique name for Vec

    351:    Output Arguments:
    352: .  X - named Vec

    354:    Level: developer

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

    358: .seealso: DMRestoreNamedGlobalVector()
    359: @*/
    360: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
    361: {
    363:   DMNamedVecLink link;

    369:   for (link=dm->namedglobal; link; link=link->next) {
    370:     PetscBool match;

    372:     PetscStrcmp(name,link->name,&match);
    373:     if (match) {
    374:       DM vdm;

    376:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    377:       VecGetDM(link->X,&vdm);
    378:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
    379:       VecSetDM(link->X,dm);
    380:       goto found;
    381:     }
    382:   }

    384:   /* Create the Vec */
    385:   PetscNew(&link);
    386:   PetscStrallocpy(name,&link->name);
    387:   DMCreateGlobalVector(dm,&link->X);
    388:   link->next      = dm->namedglobal;
    389:   dm->namedglobal = link;

    391: found:
    392:   *X           = link->X;
    393:   link->status = DMVEC_STATUS_OUT;
    394:   return(0);
    395: }

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

    400:    Collective on dm

    402:    Input Arguments:
    403: +  dm - DM on which the vector was gotten
    404: .  name - name under which the vector was gotten
    405: -  X - Vec to restore

    407:    Output Arguments:

    409:    Level: developer

    411: .seealso: DMGetNamedGlobalVector()
    412: @*/
    413: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
    414: {
    416:   DMNamedVecLink link;

    423:   for (link=dm->namedglobal; link; link=link->next) {
    424:     PetscBool match;

    426:     PetscStrcmp(name,link->name,&match);
    427:     if (match) {
    428:       DM vdm;

    430:       VecGetDM(*X,&vdm);
    431:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    432:       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);
    433:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");

    435:       link->status = DMVEC_STATUS_IN;
    436:       VecSetDM(link->X,NULL);
    437:       *X           = NULL;
    438:       return(0);
    439:     }
    440:   }
    441:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    442:   return(0);
    443: }

    445: /*@C
    446:    DMHasNamedLocalVector - check for a named, persistent local vector

    448:    Not Collective

    450:    Input Arguments:
    451: +  dm - DM to hold named vectors
    452: -  name - unique name for Vec

    454:    Output Arguments:
    455: .  exists - true if the vector was previously created

    457:    Level: developer

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

    461: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    462: @*/
    463: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
    464: {
    466:   DMNamedVecLink link;

    472:   *exists = PETSC_FALSE;
    473:   for (link=dm->namedlocal; link; link=link->next) {
    474:     PetscBool match;
    475:     PetscStrcmp(name,link->name,&match);
    476:     if (match) {
    477:       *exists = PETSC_TRUE;
    478:       break;
    479:     }
    480:   }
    481:   return(0);
    482: }

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

    487:    Not Collective

    489:    Input Arguments:
    490: +  dm - DM to hold named vectors
    491: -  name - unique name for Vec

    493:    Output Arguments:
    494: .  X - named Vec

    496:    Level: developer

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

    500: .seealso: DMGetNamedGlobalVector(), DMRestoreNamedLocalVector()
    501: @*/
    502: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
    503: {
    505:   DMNamedVecLink link;

    511:   for (link=dm->namedlocal; link; link=link->next) {
    512:     PetscBool match;

    514:     PetscStrcmp(name,link->name,&match);
    515:     if (match) {
    516:       DM vdm;

    518:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    519:       VecGetDM(link->X,&vdm);
    520:       if (vdm) SETERRQ(PetscObjectComm((PetscObject)vdm),PETSC_ERR_LIB,"Invalid vector");
    521:       VecSetDM(link->X,dm);
    522:       goto found;
    523:     }
    524:   }

    526:   /* Create the Vec */
    527:   PetscNew(&link);
    528:   PetscStrallocpy(name,&link->name);
    529:   DMCreateLocalVector(dm,&link->X);
    530:   link->next     = dm->namedlocal;
    531:   dm->namedlocal = link;

    533: found:
    534:   *X           = link->X;
    535:   link->status = DMVEC_STATUS_OUT;
    536:   return(0);
    537: }

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

    542:    Not Collective

    544:    Input Arguments:
    545: +  dm - DM on which the vector was gotten
    546: .  name - name under which the vector was gotten
    547: -  X - Vec to restore

    549:    Output Arguments:

    551:    Level: developer

    553: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
    554: @*/
    555: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
    556: {
    558:   DMNamedVecLink link;

    565:   for (link=dm->namedlocal; link; link=link->next) {
    566:     PetscBool match;

    568:     PetscStrcmp(name,link->name,&match);
    569:     if (match) {
    570:       DM vdm;

    572:       VecGetDM(*X,&vdm);
    573:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    574:       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);
    575:       if (vdm != dm) SETERRQ(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Invalid vector");

    577:       link->status = DMVEC_STATUS_IN;
    578:       VecSetDM(link->X,NULL);
    579:       *X           = NULL;
    580:       return(0);
    581:     }
    582:   }
    583:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    584:   return(0);
    585: }