Date: 2022-03-04T17:38:37+00:00

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: {
     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 Parameters:
     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 Parameters:
    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 Parameters:
    309: +  dm - DM to hold named vectors
    310: -  name - unique name for Vec

    312:    Output Parameter:
    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 Parameters:
    348: +  dm - DM to hold named vectors
    349: -  name - unique name for Vec

    351:    Output Parameter:
    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 Parameters:
    403: +  dm - DM on which the vector was gotten
    404: .  name - name under which the vector was gotten
    405: -  X - Vec to restore

    407:    Level: developer

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

    421:   for (link=dm->namedglobal; link; link=link->next) {
    422:     PetscBool match;

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

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

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

    442: /*@C
    443:    DMHasNamedLocalVector - check for a named, persistent local vector

    445:    Not Collective

    447:    Input Parameters:
    448: +  dm - DM to hold named vectors
    449: -  name - unique name for Vec

    451:    Output Parameter:
    452: .  exists - true if the vector was previously created

    454:    Level: developer

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

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

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

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

    484:    Not Collective

    486:    Input Parameters:
    487: +  dm - DM to hold named vectors
    488: -  name - unique name for Vec

    490:    Output Parameter:
    491: .  X - named Vec

    493:    Level: developer

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

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

    508:   for (link=dm->namedlocal; link; link=link->next) {
    509:     PetscBool match;

    511:     PetscStrcmp(name,link->name,&match);
    512:     if (match) {
    513:       DM vdm;

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

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

    530: found:
    531:   *X           = link->X;
    532:   link->status = DMVEC_STATUS_OUT;
    533:   return(0);
    534: }

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

    539:    Not Collective

    541:    Input Parameters:
    542: +  dm - DM on which the vector was gotten
    543: .  name - name under which the vector was gotten
    544: -  X - Vec to restore

    546:    Level: developer

    548: .seealso: DMRestoreNamedGlobalVector(), DMGetNamedLocalVector()
    549: @*/
    550: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
    551: {
    553:   DMNamedVecLink link;

    560:   for (link=dm->namedlocal; link; link=link->next) {
    561:     PetscBool match;

    563:     PetscStrcmp(name,link->name,&match);
    564:     if (match) {
    565:       DM vdm;

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

    572:       link->status = DMVEC_STATUS_IN;
    573:       VecSetDM(link->X,NULL);
    574:       *X           = NULL;
    575:       return(0);
    576:     }
    577:   }
    578:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    579: }