xref: /petsc/src/sys/objects/state.c (revision f1580f4e3ce5d5b2393648fd039d0d41b440385d)
1 
2 /*
3      Provides utility routines for manulating any type of PETSc object.
4 */
5 #include <petsc/private/petscimpl.h> /*I   "petscsys.h"    I*/
6 
7 /*@C
8    PetscObjectStateGet - Gets the state of any `PetscObject`,
9    regardless of the type.
10 
11    Not Collective
12 
13    Input Parameter:
14 .  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
15          cast with a (`PetscObject`), for example,
16          `PetscObjectStateGet`((`PetscObject`)mat,&state);
17 
18    Output Parameter:
19 .  state - the object state
20 
21    Note:
22    Object state is an integer which gets increased every time
23    the object is changed. By saving and later querying the object state
24    one can determine whether information about the object is still current.
25    Currently, state is maintained for `Vec` and `Mat` objects.
26 
27    Level: advanced
28 
29 .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()`
30 @*/
31 PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state) {
32   PetscFunctionBegin;
33   PetscValidHeader(obj, 1);
34   PetscValidIntPointer(state, 2);
35   *state = obj->state;
36   PetscFunctionReturn(0);
37 }
38 
39 /*@C
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    Note:
52     This function should be used with extreme caution. There is
53    essentially only one use for it: if the user calls Mat(Vec)GetRow(Array),
54    which increases the state, but does not alter the data, then this
55    routine can be used to reset the state.  Such a reset must be collective.
56 
57    Level: advanced
58 
59 .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
60 @*/
61 PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state) {
62   PetscFunctionBegin;
63   PetscValidHeader(obj, 1);
64   obj->state = state;
65   PetscFunctionReturn(0);
66 }
67 
68 PetscInt PetscObjectComposedDataMax = 10;
69 
70 /*@C
71    PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
72 
73    Not Collective
74 
75    Output parameter:
76 .  id - an identifier under which data can be stored
77 
78    Level: developer
79 
80    Notes:
81    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.
82 
83    `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object
84 
85 .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
86           `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
87           `PetscObjectCompose()`,  `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
88           `PetscObjectComposedDataSetScalarstar()`, `PetscObjectComposedDataSetScalarstar()`
89 @*/
90 PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id) {
91   static PetscInt globalcurrentstate = 0;
92 
93   PetscFunctionBegin;
94   *id = globalcurrentstate++;
95   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
96   PetscFunctionReturn(0);
97 }
98 
99 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj) {
100   PetscInt         *ar = obj->intcomposeddata, *new_ar, n = obj->int_idmax, new_n;
101   PetscObjectState *ir = obj->intcomposedstate, *new_ir;
102 
103   PetscFunctionBegin;
104   new_n = PetscObjectComposedDataMax;
105   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
106   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscInt)));
107   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
108   PetscCall(PetscFree2(ar, ir));
109   obj->int_idmax        = new_n;
110   obj->intcomposeddata  = new_ar;
111   obj->intcomposedstate = new_ir;
112   PetscFunctionReturn(0);
113 }
114 
115 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj) {
116   PetscInt        **ar = obj->intstarcomposeddata, **new_ar, n = obj->intstar_idmax, new_n;
117   PetscObjectState *ir = obj->intstarcomposedstate, *new_ir;
118 
119   PetscFunctionBegin;
120   new_n = PetscObjectComposedDataMax;
121   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
122   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscInt *)));
123   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
124   PetscCall(PetscFree2(ar, ir));
125   obj->intstar_idmax        = new_n;
126   obj->intstarcomposeddata  = new_ar;
127   obj->intstarcomposedstate = new_ir;
128   PetscFunctionReturn(0);
129 }
130 
131 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj) {
132   PetscReal        *ar = obj->realcomposeddata, *new_ar;
133   PetscObjectState *ir = obj->realcomposedstate, *new_ir;
134   PetscInt          n  = obj->real_idmax, new_n;
135 
136   PetscFunctionBegin;
137   new_n = PetscObjectComposedDataMax;
138   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
139   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscReal)));
140   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
141   PetscCall(PetscFree2(ar, ir));
142   obj->real_idmax        = new_n;
143   obj->realcomposeddata  = new_ar;
144   obj->realcomposedstate = new_ir;
145   PetscFunctionReturn(0);
146 }
147 
148 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj) {
149   PetscReal       **ar = obj->realstarcomposeddata, **new_ar;
150   PetscObjectState *ir = obj->realstarcomposedstate, *new_ir;
151   PetscInt          n  = obj->realstar_idmax, new_n;
152 
153   PetscFunctionBegin;
154   new_n = PetscObjectComposedDataMax;
155   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
156   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscReal *)));
157   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
158   PetscCall(PetscFree2(ar, ir));
159   obj->realstar_idmax        = new_n;
160   obj->realstarcomposeddata  = new_ar;
161   obj->realstarcomposedstate = new_ir;
162   PetscFunctionReturn(0);
163 }
164 
165 PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj) {
166   PetscScalar      *ar = obj->scalarcomposeddata, *new_ar;
167   PetscObjectState *ir = obj->scalarcomposedstate, *new_ir;
168   PetscInt          n  = obj->scalar_idmax, new_n;
169 
170   PetscFunctionBegin;
171   new_n = PetscObjectComposedDataMax;
172   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
173   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscScalar)));
174   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
175   PetscCall(PetscFree2(ar, ir));
176   obj->scalar_idmax        = new_n;
177   obj->scalarcomposeddata  = new_ar;
178   obj->scalarcomposedstate = new_ir;
179   PetscFunctionReturn(0);
180 }
181 
182 PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj) {
183   PetscScalar     **ar = obj->scalarstarcomposeddata, **new_ar;
184   PetscObjectState *ir = obj->scalarstarcomposedstate, *new_ir;
185   PetscInt          n  = obj->scalarstar_idmax, new_n;
186 
187   PetscFunctionBegin;
188   new_n = PetscObjectComposedDataMax;
189   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
190   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscScalar *)));
191   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
192   PetscCall(PetscFree2(ar, ir));
193   obj->scalarstar_idmax        = new_n;
194   obj->scalarstarcomposeddata  = new_ar;
195   obj->scalarstarcomposedstate = new_ir;
196   PetscFunctionReturn(0);
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 @*/
217 PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id) {
218   PetscFunctionBegin;
219   PetscValidHeader(obj, 1);
220   PetscValidIntPointer(id, 2);
221   *id = obj->id;
222   PetscFunctionReturn(0);
223 }
224 
225 /*@
226    PetscObjectCompareId - compares the objects ID with a given id
227 
228    Not Collective
229 
230    Input Parameters:
231 +  obj - object
232 -  id - integer ID
233 
234    Output Parameter;
235 .  eq - the ids are equal
236 
237    Level: developer
238 
239    Note:
240    The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
241 
242 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
243 @*/
244 PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq) {
245   PetscObjectId oid;
246 
247   PetscFunctionBegin;
248   PetscValidHeader(obj, 1);
249   PetscValidBoolPointer(eq, 3);
250   PetscCall(PetscObjectGetId(obj, &oid));
251   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
252   PetscFunctionReturn(0);
253 }
254