xref: /petsc/src/sys/objects/state.c (revision df4cd43f92eaa320656440c40edb1046daee8f75)
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 {
33   PetscFunctionBegin;
34   PetscValidHeader(obj, 1);
35   PetscValidIntPointer(state, 2);
36   *state = obj->state;
37   PetscFunctionReturn(PETSC_SUCCESS);
38 }
39 
40 /*@C
41    PetscObjectStateSet - Sets the state of any `PetscObject`,
42    regardless of the type.
43 
44    Logically Collective
45 
46    Input Parameters:
47 +  obj - any PETSc object, for example a `Vec`, `Mat` or `KSP`. This must be
48          cast with a (`PetscObject`), for example,
49          `PetscObjectStateSet`((`PetscObject`)mat,state);
50 -  state - the object state
51 
52    Note:
53     This function should be used with extreme caution. There is
54    essentially only one use for it: if the user calls Mat(Vec)GetRow(Array),
55    which increases the state, but does not alter the data, then this
56    routine can be used to reset the state.  Such a reset must be collective.
57 
58    Level: advanced
59 
60 .seealso: `PetscObjectStateGet()`, `PetscObjectStateIncrease()`
61 @*/
62 PetscErrorCode PetscObjectStateSet(PetscObject obj, PetscObjectState state)
63 {
64   PetscFunctionBegin;
65   PetscValidHeader(obj, 1);
66   obj->state = state;
67   PetscFunctionReturn(PETSC_SUCCESS);
68 }
69 
70 PetscInt PetscObjectComposedDataMax = 10;
71 
72 /*@C
73    PetscObjectComposedDataRegister - Get an available id for composing data with a `PetscObject`
74 
75    Not Collective
76 
77    Output parameter:
78 .  id - an identifier under which data can be stored
79 
80    Level: developer
81 
82    Notes:
83    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 
85    `PetscObjectCompose()` and  `PetscObjectQuery()` provide a way to attach any data to an object
86 
87 .seealso: `PetscObjectComposedDataSetInt()`, `PetscObjectComposedDataSetReal()`, `PetscObjectComposedDataGetReal()`, `PetscObjectComposedDataSetIntstar()`,
88           `PetscObjectComposedDataSetIntstar()`, `PetscObjectComposedDataGetInt()`, `PetscObject`,
89           `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`,
90           `PetscObjectComposedDataSetScalarstar()`, `PetscObjectComposedDataSetScalarstar()`
91 @*/
92 PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id)
93 {
94   static PetscInt globalcurrentstate = 0;
95 
96   PetscFunctionBegin;
97   *id = globalcurrentstate++;
98   if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10;
99   PetscFunctionReturn(PETSC_SUCCESS);
100 }
101 
102 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj)
103 {
104   PetscInt         *ar = obj->intcomposeddata, *new_ar, n = obj->int_idmax, new_n;
105   PetscObjectState *ir = obj->intcomposedstate, *new_ir;
106 
107   PetscFunctionBegin;
108   new_n = PetscObjectComposedDataMax;
109   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
110   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscInt)));
111   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
112   PetscCall(PetscFree2(ar, ir));
113   obj->int_idmax        = new_n;
114   obj->intcomposeddata  = new_ar;
115   obj->intcomposedstate = new_ir;
116   PetscFunctionReturn(PETSC_SUCCESS);
117 }
118 
119 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj)
120 {
121   PetscInt        **ar = obj->intstarcomposeddata, **new_ar, n = obj->intstar_idmax, new_n;
122   PetscObjectState *ir = obj->intstarcomposedstate, *new_ir;
123 
124   PetscFunctionBegin;
125   new_n = PetscObjectComposedDataMax;
126   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
127   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscInt *)));
128   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
129   PetscCall(PetscFree2(ar, ir));
130   obj->intstar_idmax        = new_n;
131   obj->intstarcomposeddata  = new_ar;
132   obj->intstarcomposedstate = new_ir;
133   PetscFunctionReturn(PETSC_SUCCESS);
134 }
135 
136 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj)
137 {
138   PetscReal        *ar = obj->realcomposeddata, *new_ar;
139   PetscObjectState *ir = obj->realcomposedstate, *new_ir;
140   PetscInt          n  = obj->real_idmax, new_n;
141 
142   PetscFunctionBegin;
143   new_n = PetscObjectComposedDataMax;
144   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
145   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscReal)));
146   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
147   PetscCall(PetscFree2(ar, ir));
148   obj->real_idmax        = new_n;
149   obj->realcomposeddata  = new_ar;
150   obj->realcomposedstate = new_ir;
151   PetscFunctionReturn(PETSC_SUCCESS);
152 }
153 
154 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj)
155 {
156   PetscReal       **ar = obj->realstarcomposeddata, **new_ar;
157   PetscObjectState *ir = obj->realstarcomposedstate, *new_ir;
158   PetscInt          n  = obj->realstar_idmax, new_n;
159 
160   PetscFunctionBegin;
161   new_n = PetscObjectComposedDataMax;
162   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
163   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscReal *)));
164   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
165   PetscCall(PetscFree2(ar, ir));
166   obj->realstar_idmax        = new_n;
167   obj->realstarcomposeddata  = new_ar;
168   obj->realstarcomposedstate = new_ir;
169   PetscFunctionReturn(PETSC_SUCCESS);
170 }
171 
172 PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj)
173 {
174   PetscScalar      *ar = obj->scalarcomposeddata, *new_ar;
175   PetscObjectState *ir = obj->scalarcomposedstate, *new_ir;
176   PetscInt          n  = obj->scalar_idmax, new_n;
177 
178   PetscFunctionBegin;
179   new_n = PetscObjectComposedDataMax;
180   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
181   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscScalar)));
182   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
183   PetscCall(PetscFree2(ar, ir));
184   obj->scalar_idmax        = new_n;
185   obj->scalarcomposeddata  = new_ar;
186   obj->scalarcomposedstate = new_ir;
187   PetscFunctionReturn(PETSC_SUCCESS);
188 }
189 
190 PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj)
191 {
192   PetscScalar     **ar = obj->scalarstarcomposeddata, **new_ar;
193   PetscObjectState *ir = obj->scalarstarcomposedstate, *new_ir;
194   PetscInt          n  = obj->scalarstar_idmax, new_n;
195 
196   PetscFunctionBegin;
197   new_n = PetscObjectComposedDataMax;
198   PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir));
199   PetscCall(PetscMemcpy(new_ar, ar, n * sizeof(PetscScalar *)));
200   PetscCall(PetscMemcpy(new_ir, ir, n * sizeof(PetscObjectState)));
201   PetscCall(PetscFree2(ar, ir));
202   obj->scalarstar_idmax        = new_n;
203   obj->scalarstarcomposeddata  = new_ar;
204   obj->scalarstarcomposedstate = new_ir;
205   PetscFunctionReturn(PETSC_SUCCESS);
206 }
207 
208 /*@
209    PetscObjectGetId - get a unique object ID for the `PetscObject`
210 
211    Not Collective
212 
213    Input Parameter:
214 .  obj - object
215 
216    Output Parameter:
217 .  id - integer ID
218 
219    Level: developer
220 
221    Note:
222    The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
223 
224 .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()`
225 @*/
226 PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id)
227 {
228   PetscFunctionBegin;
229   PetscValidHeader(obj, 1);
230   PetscValidIntPointer(id, 2);
231   *id = obj->id;
232   PetscFunctionReturn(PETSC_SUCCESS);
233 }
234 
235 /*@
236    PetscObjectCompareId - compares the objects ID with a given id
237 
238    Not Collective
239 
240    Input Parameters:
241 +  obj - object
242 -  id - integer ID
243 
244    Output Parameter;
245 .  eq - the ids are equal
246 
247    Level: developer
248 
249    Note:
250    The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality.
251 
252 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()`
253 @*/
254 PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq)
255 {
256   PetscObjectId oid;
257 
258   PetscFunctionBegin;
259   PetscValidHeader(obj, 1);
260   PetscValidBoolPointer(eq, 3);
261   PetscCall(PetscObjectGetId(obj, &oid));
262   *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE;
263   PetscFunctionReturn(PETSC_SUCCESS);
264 }
265