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:   const char             *ar = *composed;
108:   const 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: }