Actual source code: state.c

      1: /*
      2:      Provides utility routines for manulating any type of PETSc object.
      3: */
      4: #include <petsc/private/petscimpl.h>

      6: /*@
      7:   PetscObjectStateGet - Gets the state of any `PetscObject`,
      8:   regardless of the type.

     10:   Not Collective

     12:   Input Parameter:
     13: . obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
     14:          cast with a (`PetscObject`), for example,
     15:          `PetscObjectStateGet`((`PetscObject`)mat,&state);

     17:   Output Parameter:
     18: . state - the object state

     20:   Level: advanced

     22:   Note:
     23:   Object state is an integer which gets increased every time
     24:   the object is changed. By saving and later querying the object state
     25:   one can determine whether information about the object is still current.
     26:   Currently, state is maintained for `Vec` and `Mat` objects.

     28: .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
     29: @*/
     30: PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state)
     31: {
     32:   PetscFunctionBegin;
     34:   PetscAssertPointer(state, 2);
     35:   *state = obj->state;
     36:   PetscFunctionReturn(PETSC_SUCCESS);
     37: }

     39: /*@
     40:   PetscObjectStateSet - Sets the state of any `PetscObject`,
     41:   regardless of the type.

     43:   Logically Collective

     45:   Input Parameters:
     46: + obj   - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
     47:          cast with a (`PetscObject`), for example,
     48:          `PetscObjectStateSet`((`PetscObject`)mat,state);
     49: - state - the object state

     51:   Level: advanced

     53:   Note:
     54:   This function should be used with extreme caution. There is
     55:   essentially only one use for it: if the user calls `Mat`(`Vec`)GetRow(Array),
     56:   which increases the state, but does not alter the data, then this
     57:   routine can be used to reset the state.  Such a reset must be collective.

     59: .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
     60: @*/
     61: PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
     62: {
     63:   PetscFunctionBegin;
     65:   obj->state = state;
     66:   PetscFunctionReturn(PETSC_SUCCESS);
     67: }

     69: PetscInt PetscObjectComposedDataMax = 10;

     71: /*@C
     72:   PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`

     74:   Not Collective

     76:   Output Parameter:
     77: . id - an identifier under which data can be stored

     79:   Level: developer

     81:   Notes:
     82:   You must keep this value (for example in a global variable) in order to attach the data to an object or access in an object.

     84:   `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object

     86: .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
     87:           `PetscObjectComposedDataGetInt()`, `PetscObject`,
     88:           `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
     89:           `PetscObjectComposedDataSetScalarstar()`
     90: @*/
     91: PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
     92: {
     93:   static PetscInt globalcurrentstate = 0;

     95:   PetscFunctionBegin;
     96:   PetscAssertPointer(id, 1);
     97:   *id = globalcurrentstate++;
     98:   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
     99:   PetscFunctionReturn(PETSC_SUCCESS);
    100: }

    102: static PetscErrorCode PetscObjectComposedDataIncrease_(PetscInt *id_max, char **composed, PetscObjectState **composed_state, size_t obj_size)
    103: {
    104:   // must use char here since PetscCalloc2() and PetscMemcpy() use sizeof(**ptr), so if
    105:   // composed is void ** (to match PetscObjectComposedDataStarIncrease_()) that would expand to
    106:   // sizeof(void) which is illegal.
    107:   char             *ar = *composed;
    108:   PetscObjectState *ir = *composed_state;
    109:   const PetscInt    n = *id_max, new_n = PetscObjectComposedDataMax;
    110:   char             *new_ar;
    111:   PetscObjectState *new_ir;

    113:   PetscFunctionBegin;
    114:   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed data ids: %" PetscInt_FMT " < 0", n);
    115:   PetscCall(PetscCalloc2(new_n * obj_size, &new_ar, new_n, &new_ir));
    116:   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
    117:   PetscCall(PetscArraycpy(new_ir, ir, n));
    118:   PetscCall(PetscFree2(ar, ir));
    119:   *id_max         = new_n;
    120:   *composed       = new_ar;
    121:   *composed_state = new_ir;
    122:   PetscFunctionReturn(PETSC_SUCCESS);
    123: }

    125: #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed)))

    127: static PetscErrorCode PetscObjectComposedDataStarIncrease_(PetscInt *id_max, void ***composed, PetscObjectState **composed_state, size_t obj_size)
    128: {
    129:   void                  **ar = *composed;
    130:   const PetscObjectState *ir = *composed_state;
    131:   const PetscInt          n = *id_max, new_n = PetscObjectComposedDataMax;
    132:   void                  **new_ar;
    133:   PetscObjectState       *new_ir;

    135:   PetscFunctionBegin;
    136:   PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed star data ids: %" PetscInt_FMT " < 0", n);
    137:   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
    138:   PetscCall(PetscMemcpy(new_ar, ar, n * obj_size));
    139:   PetscCall(PetscArraycpy(new_ir, ir, n));
    140:   PetscCall(PetscFree2(ar, ir));
    141:   *id_max         = new_n;
    142:   *composed       = new_ar;
    143:   *composed_state = new_ir;
    144:   PetscFunctionReturn(PETSC_SUCCESS);
    145: }

    147: #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed)))

    149: PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
    150: {
    151:   PetscFunctionBegin;
    152:   PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate));
    153:   PetscFunctionReturn(PETSC_SUCCESS);
    154: }

    156: PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
    157: {
    158:   PetscFunctionBegin;
    159:   PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate));
    160:   PetscFunctionReturn(PETSC_SUCCESS);
    161: }

    163: PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
    164: {
    165:   PetscFunctionBegin;
    166:   PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate));
    167:   PetscFunctionReturn(PETSC_SUCCESS);
    168: }

    170: PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
    171: {
    172:   PetscFunctionBegin;
    173:   PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate));
    174:   PetscFunctionReturn(PETSC_SUCCESS);
    175: }

    177: PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj)
    178: {
    179:   PetscFunctionBegin;
    180: #if PetscDefined(USE_COMPLEX)
    181:   PetscCall(PetscObjectComposedDataIncrease(&obj->scalar_idmax, &obj->scalarcomposeddata, &obj->scalarcomposedstate));
    182: #else
    183:   PetscCall(PetscObjectComposedDataIncreaseReal(obj));
    184: #endif
    185:   PetscFunctionReturn(PETSC_SUCCESS);
    186: }

    188: PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)
    189: {
    190:   PetscFunctionBegin;
    191: #if PetscDefined(USE_COMPLEX)
    192:   PetscCall(PetscObjectComposedDataStarIncrease(&obj->scalarstar_idmax, &obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate));
    193: #else
    194:   PetscCall(PetscObjectComposedDataIncreaseRealstar(obj));
    195: #endif
    196:   PetscFunctionReturn(PETSC_SUCCESS);
    197: }

    199: /*@
    200:   PetscObjectGetId - get a unique object ID for the `PetscObject`

    202:   Not Collective

    204:   Input Parameter:
    205: . obj - object

    207:   Output Parameter:
    208: . id - integer ID

    210:   Level: developer

    212:   Note:
    213:   The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.

    215: .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
    216: @*/
    217: PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
    218: {
    219:   PetscFunctionBegin;
    221:   PetscAssertPointer(id, 2);
    222:   *id = obj->id;
    223:   PetscFunctionReturn(PETSC_SUCCESS);
    224: }

    226: /*@
    227:   PetscObjectCompareId - compares the objects ID with a given id

    229:   Not Collective

    231:   Input Parameters:
    232: + obj - object
    233: - id  - integer ID

    235:   Output Parameter:
    236: . eq - the ids are equal

    238:   Level: developer

    240:   Note:
    241:   The object ID may be different on different processes, but object IDs are never reused so
    242:   local equality implies global equality.

    244: .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
    245: @*/
    246: PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
    247: {
    248:   PetscObjectId oid;

    250:   PetscFunctionBegin;
    252:   PetscAssertPointer(eq, 3);
    253:   PetscCall(PetscObjectGetId(obj, &oid));
    254:   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
    255:   PetscFunctionReturn(PETSC_SUCCESS);
    256: }