Actual source code: dmget.c
petsc-3.10.5 2019-03-28
Report Typos and Errors

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

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

      7:    Not Collective

      9:    Input Parameter:
     10: .  dm - the distributed array

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

     15:    Level: beginner

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

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

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

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

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

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

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

     53: alldone:
     54:   for (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 Seq PETSc vector that
     65:      obtained from DMGetLocalVector(). Do not use with vector obtained via
     66:      DMCreateLocalVector().

     68:    Not Collective

     70:    Input Parameter:
     71: +  dm - the distributed array
     72: -  g - the local vector

     74:    Level: beginner

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

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

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

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

    111:    Collective on DM

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

    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: .keywords: distributed array, create, Global, vector

    136: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    137:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    138:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    139:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    141: @*/
    142: PetscErrorCode  DMGetGlobalVector(DM dm,Vec *g)
    143: {
    145:   PetscInt       i;

    150:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    151:     if (dm->globalin[i]) {
    152:       *g              = dm->globalin[i];
    153:       dm->globalin[i] = NULL;
    154:       goto alldone;
    155:     }
    156:   }
    157:   DMCreateGlobalVector(dm,g);

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

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

    172:    Collective on DM

    174:    Input Parameter:
    175: .  dm - the distributed array

    177:    Level: developer

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

    181: .seealso: DMCreateGlobalVector(), VecDuplicate(), VecDuplicateVecs(),
    182:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMGlobalToLocalBegin(),
    183:           DMGlobalToLocalEnd(), DMLocalToGlobalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    184:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    186: @*/
    187: PetscErrorCode  DMClearGlobalVectors(DM dm)
    188: {
    190:   PetscInt       i;

    194:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    195:     Vec g;
    196:     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()");
    197:     g = dm->globalin[i];
    198:     dm->globalin[i] = NULL;
    199:     VecDestroy(&g);
    200:   }
    201:   return(0);
    202: }

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

    207:    Collective on DM

    209:    Input Parameter:
    210: .  dm - the distributed array

    212:    Level: developer

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

    216: .seealso: DMCreateLocalVector(), VecDuplicate(), VecDuplicateVecs(),
    217:           DMDACreate1d(), DMDACreate2d(), DMDACreate3d(), DMLocalToLocalBegin(),
    218:           DMLocalToLocalEnd(), DMLocalToLocalBegin(), DMCreateLocalVector(), DMRestoreLocalVector()
    219:           VecStrideMax(), VecStrideMin(), VecStrideNorm()

    221: @*/
    222: PetscErrorCode  DMClearLocalVectors(DM dm)
    223: {
    225:   PetscInt       i;

    229:   for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    230:     Vec g;
    231:     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()");
    232:     g = dm->localin[i];
    233:     dm->localin[i] = NULL;
    234:     VecDestroy(&g);
    235:   }
    236:   return(0);
    237: }

    239: /*@
    240:    DMRestoreGlobalVector - Returns a Seq PETSc vector that
    241:      obtained from DMGetGlobalVector(). Do not use with vector obtained via
    242:      DMCreateGlobalVector().

    244:    Not Collective

    246:    Input Parameter:
    247: +  dm - the distributed array
    248: -  g - the global vector

    250:    Level: beginner

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

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

    266:   VecLocked(*g, 2);
    267:   for (j=0; j<DM_MAX_WORK_VECTORS; j++) {
    268:     if (*g == dm->globalout[j]) {
    269:       dm->globalout[j] = NULL;
    270:       for (i=0; i<DM_MAX_WORK_VECTORS; i++) {
    271:         if (!dm->globalin[i]) {
    272:           dm->globalin[i] = *g;
    273:           goto alldone;
    274:         }
    275:       }
    276:     }
    277:   }
    278:   VecDestroy(g);
    279: alldone:
    280:   *g = NULL;
    281:   return(0);
    282: }

    284: /*@C
    285:    DMHasNamedGlobalVector - check for a named, persistent global vector

    287:    Not Collective

    289:    Input Arguments:
    290: +  dm - DM to hold named vectors
    291: -  name - unique name for Vec

    293:    Output Arguments:
    294: .  exists - true if the vector was previously created

    296:    Level: developer

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

    300: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    301: @*/
    302: PetscErrorCode DMHasNamedGlobalVector(DM dm,const char *name,PetscBool *exists)
    303: {
    305:   DMNamedVecLink link;

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

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

    326:    Collective on DM

    328:    Input Arguments:
    329: +  dm - DM to hold named vectors
    330: -  name - unique name for Vec

    332:    Output Arguments:
    333: .  X - named Vec

    335:    Level: developer

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

    339: .seealso: DMRestoreNamedGlobalVector()
    340: @*/
    341: PetscErrorCode DMGetNamedGlobalVector(DM dm,const char *name,Vec *X)
    342: {
    344:   DMNamedVecLink link;

    350:   for (link=dm->namedglobal; link; link=link->next) {
    351:     PetscBool match;
    352:     PetscStrcmp(name,link->name,&match);
    353:     if (match) {
    354:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    355:       goto found;
    356:     }
    357:   }

    359:   /* Create the Vec */
    360:   PetscNew(&link);
    361:   PetscStrallocpy(name,&link->name);
    362:   DMCreateGlobalVector(dm,&link->X);
    363:   link->next      = dm->namedglobal;
    364:   dm->namedglobal = link;

    366: found:
    367:   *X           = link->X;
    368:   link->status = DMVEC_STATUS_OUT;
    369:   return(0);
    370: }

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

    375:    Collective on DM

    377:    Input Arguments:
    378: +  dm - DM on which the vector was gotten
    379: .  name - name under which the vector was gotten
    380: -  X - Vec to restore

    382:    Output Arguments:

    384:    Level: developer

    386: .seealso: DMGetNamedGlobalVector()
    387: @*/
    388: PetscErrorCode DMRestoreNamedGlobalVector(DM dm,const char *name,Vec *X)
    389: {
    391:   DMNamedVecLink link;

    398:   for (link=dm->namedglobal; link; link=link->next) {
    399:     PetscBool match;
    400:     PetscStrcmp(name,link->name,&match);
    401:     if (match) {
    402:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    403:       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);
    404:       link->status = DMVEC_STATUS_IN;
    405:       *X           = NULL;
    406:       return(0);
    407:     }
    408:   }
    409:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    410:   return(0);
    411: }

    413: /*@C
    414:    DMHasNamedLocalVector - check for a named, persistent local vector

    416:    Not Collective

    418:    Input Arguments:
    419: +  dm - DM to hold named vectors
    420: -  name - unique name for Vec

    422:    Output Arguments:
    423: .  exists - true if the vector was previously created

    425:    Level: developer

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

    429: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    430: @*/
    431: PetscErrorCode DMHasNamedLocalVector(DM dm,const char *name,PetscBool *exists)
    432: {
    434:   DMNamedVecLink link;

    440:   *exists = PETSC_FALSE;
    441:   for (link=dm->namedlocal; link; link=link->next) {
    442:     PetscBool match;
    443:     PetscStrcmp(name,link->name,&match);
    444:     if (match) {
    445:       *exists = PETSC_TRUE;
    446:       break;
    447:     }
    448:   }
    449:   return(0);
    450: }

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

    455:    Not Collective

    457:    Input Arguments:
    458: +  dm - DM to hold named vectors
    459: -  name - unique name for Vec

    461:    Output Arguments:
    462: .  X - named Vec

    464:    Level: developer

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

    468: .seealso: DMGetNamedGlobalVector(),DMRestoreNamedLocalVector()
    469: @*/
    470: PetscErrorCode DMGetNamedLocalVector(DM dm,const char *name,Vec *X)
    471: {
    473:   DMNamedVecLink link;

    479:   for (link=dm->namedlocal; link; link=link->next) {
    480:     PetscBool match;
    481:     PetscStrcmp(name,link->name,&match);
    482:     if (match) {
    483:       if (link->status != DMVEC_STATUS_IN) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' already checked out",name);
    484:       goto found;
    485:     }
    486:   }

    488:   /* Create the Vec */
    489:   PetscNew(&link);
    490:   PetscStrallocpy(name,&link->name);
    491:   DMCreateLocalVector(dm,&link->X);
    492:   link->next     = dm->namedlocal;
    493:   dm->namedlocal = link;

    495: found:
    496:   *X           = link->X;
    497:   link->status = DMVEC_STATUS_OUT;
    498:   return(0);
    499: }

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

    504:    Not Collective

    506:    Input Arguments:
    507: +  dm - DM on which the vector was gotten
    508: .  name - name under which the vector was gotten
    509: -  X - Vec to restore

    511:    Output Arguments:

    513:    Level: developer

    515: .seealso: DMRestoreNamedGlobalVector(),DMGetNamedLocalVector()
    516: @*/
    517: PetscErrorCode DMRestoreNamedLocalVector(DM dm,const char *name,Vec *X)
    518: {
    520:   DMNamedVecLink link;

    527:   for (link=dm->namedlocal; link; link=link->next) {
    528:     PetscBool match;
    529:     PetscStrcmp(name,link->name,&match);
    530:     if (match) {
    531:       if (link->status != DMVEC_STATUS_OUT) SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Vec name '%s' was not checked out",name);
    532:       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);
    533:       link->status = DMVEC_STATUS_IN;
    534:       *X           = NULL;
    535:       return(0);
    536:     }
    537:   }
    538:   SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_INCOMP,"Could not find Vec name '%s' to restore",name);
    539:   return(0);
    540: }