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: /*@C
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: /*@C
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: }