1 /*
2 Provides utility routines for manulating any type of PETSc object.
3 */
4 #include <petsc/private/petscimpl.h> /*I "petscsys.h" I*/
5
6 /*@
7 PetscObjectStateGet - Gets the state of any `PetscObject`,
8 regardless of the type.
9
10 Not Collective
11
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);
16
17 Output Parameter:
18 . state - the object state
19
20 Level: advanced
21
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.
27
28 .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
29 @*/
PetscObjectStateGet(PetscObject obj,PetscObjectState * state)30 PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state)
31 {
32 PetscFunctionBegin;
33 PetscValidHeader(obj, 1);
34 PetscAssertPointer(state, 2);
35 *state = obj->state;
36 PetscFunctionReturn(PETSC_SUCCESS);
37 }
38
39 /*@
40 PetscObjectStateSet - Sets the state of any `PetscObject`,
41 regardless of the type.
42
43 Logically Collective
44
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
50
51 Level: advanced
52
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.
58
59 .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
60 @*/
PetscObjectStateSet(PetscObject obj,PetscObjectState state)61 PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
62 {
63 PetscFunctionBegin;
64 PetscValidHeader(obj, 1);
65 obj->state = state;
66 PetscFunctionReturn(PETSC_SUCCESS);
67 }
68
69 PetscInt PetscObjectComposedDataMax = 10;
70
71 /*@C
72 PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
73
74 Not Collective
75
76 Output Parameter:
77 . id - an identifier under which data can be stored
78
79 Level: developer
80
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.
83
84 `PetscObjectCompose()` and `PetscObjectQuery()` provide a way to attach any data to an object
85
86 .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
87 `PetscObjectComposedDataGetInt()`, `PetscObject`,
88 `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
89 `PetscObjectComposedDataSetScalarstar()`
90 @*/
PetscObjectComposedDataRegister(PetscInt * id)91 PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
92 {
93 static PetscInt globalcurrentstate = 0;
94
95 PetscFunctionBegin;
96 PetscAssertPointer(id, 1);
97 *id = globalcurrentstate++;
98 if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
99 PetscFunctionReturn(PETSC_SUCCESS);
100 }
101
PetscObjectComposedDataIncrease_(PetscInt * id_max,char ** composed,PetscObjectState ** composed_state,size_t obj_size)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;
112
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 }
124
125 #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed)))
126
PetscObjectComposedDataStarIncrease_(PetscInt * id_max,void *** composed,PetscObjectState ** composed_state,size_t obj_size)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;
134
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 }
146
147 #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed)))
148
PetscObjectComposedDataIncreaseInt(PetscObject obj)149 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
150 {
151 PetscFunctionBegin;
152 PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate));
153 PetscFunctionReturn(PETSC_SUCCESS);
154 }
155
PetscObjectComposedDataIncreaseIntstar(PetscObject obj)156 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
157 {
158 PetscFunctionBegin;
159 PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate));
160 PetscFunctionReturn(PETSC_SUCCESS);
161 }
162
PetscObjectComposedDataIncreaseReal(PetscObject obj)163 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
164 {
165 PetscFunctionBegin;
166 PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate));
167 PetscFunctionReturn(PETSC_SUCCESS);
168 }
169
PetscObjectComposedDataIncreaseRealstar(PetscObject obj)170 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
171 {
172 PetscFunctionBegin;
173 PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate));
174 PetscFunctionReturn(PETSC_SUCCESS);
175 }
176
PetscObjectComposedDataIncreaseScalar(PetscObject obj)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 }
187
PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)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 }
198
199 /*@
200 PetscObjectGetId - get a unique object ID for the `PetscObject`
201
202 Not Collective
203
204 Input Parameter:
205 . obj - object
206
207 Output Parameter:
208 . id - integer ID
209
210 Level: developer
211
212 Note:
213 The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
214
215 .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
216 @*/
PetscObjectGetId(PetscObject obj,PetscObjectId * id)217 PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
218 {
219 PetscFunctionBegin;
220 PetscValidHeader(obj, 1);
221 PetscAssertPointer(id, 2);
222 *id = obj->id;
223 PetscFunctionReturn(PETSC_SUCCESS);
224 }
225
226 /*@
227 PetscObjectCompareId - compares the objects ID with a given id
228
229 Not Collective
230
231 Input Parameters:
232 + obj - object
233 - id - integer ID
234
235 Output Parameter:
236 . eq - the ids are equal
237
238 Level: developer
239
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.
243
244 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
245 @*/
PetscObjectCompareId(PetscObject obj,PetscObjectId id,PetscBool * eq)246 PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
247 {
248 PetscObjectId oid;
249
250 PetscFunctionBegin;
251 PetscValidHeader(obj, 1);
252 PetscAssertPointer(eq, 3);
253 PetscCall(PetscObjectGetId(obj, &oid));
254 *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
255 PetscFunctionReturn(PETSC_SUCCESS);
256 }
257