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 Level: advanced 22 23 Note: 24 Object state is an integer which gets increased every time 25 the object is changed. By saving and later querying the object state 26 one can determine whether information about the object is still current. 27 Currently, state is maintained for `Vec` and `Mat` objects. 28 29 .seealso: `PetscObjectStateIncrease()`, `PetscObjectStateSet()` 30 @*/ 31 PetscErrorCode PetscObjectStateGet(PetscObject obj, PetscObjectState *state) 32 { 33 PetscFunctionBegin; 34 PetscValidHeader(obj, 1); 35 PetscAssertPointer(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 Level: advanced 53 54 Note: 55 This function should be used with extreme caution. There is 56 essentially only one use for it: if the user calls `Mat`(`Vec`)GetRow(Array), 57 which increases the state, but does not alter the data, then this 58 routine can be used to reset the state. Such a reset must be collective. 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 `PetscObjectComposedDataGetInt()`, `PetscObject`, 89 `PetscObjectCompose()`, `PetscObjectQuery()`, `PetscObjectComposedDataSetRealstar()`, `PetscObjectComposedDataGetScalarstar()`, 90 `PetscObjectComposedDataSetScalarstar()` 91 @*/ 92 PetscErrorCode PetscObjectComposedDataRegister(PetscInt *id) 93 { 94 static PetscInt globalcurrentstate = 0; 95 96 PetscFunctionBegin; 97 PetscAssertPointer(id, 1); 98 *id = globalcurrentstate++; 99 if (globalcurrentstate > PetscObjectComposedDataMax) PetscObjectComposedDataMax += 10; 100 PetscFunctionReturn(PETSC_SUCCESS); 101 } 102 103 static PetscErrorCode PetscObjectComposedDataIncrease_(PetscInt *id_max, char **composed, PetscObjectState **composed_state, size_t obj_size) 104 { 105 // must use char here since PetscCalloc2() and PetscMemcpy() use sizeof(**ptr), so if 106 // composed is void ** (to match PetscObjectComposedDataStarIncrease_()) that would expand to 107 // sizeof(void) which is illegal. 108 const char *ar = *composed; 109 const PetscObjectState *ir = *composed_state; 110 const PetscInt n = *id_max, new_n = PetscObjectComposedDataMax; 111 char *new_ar; 112 PetscObjectState *new_ir; 113 114 PetscFunctionBegin; 115 PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed data ids: %" PetscInt_FMT " < 0", n); 116 PetscCall(PetscCalloc2(new_n * obj_size, &new_ar, new_n, &new_ir)); 117 PetscCall(PetscMemcpy(new_ar, ar, n * obj_size)); 118 PetscCall(PetscArraycpy(new_ir, ir, n)); 119 PetscCall(PetscFree2(ar, ir)); 120 *id_max = new_n; 121 *composed = new_ar; 122 *composed_state = new_ir; 123 PetscFunctionReturn(PETSC_SUCCESS); 124 } 125 126 #define PetscObjectComposedDataIncrease(id_max, composed, composed_state) PetscObjectComposedDataIncrease_(id_max, (char **)(composed), composed_state, sizeof(**(composed))) 127 128 static PetscErrorCode PetscObjectComposedDataStarIncrease_(PetscInt *id_max, void ***composed, PetscObjectState **composed_state, size_t obj_size) 129 { 130 void **ar = *composed; 131 const PetscObjectState *ir = *composed_state; 132 const PetscInt n = *id_max, new_n = PetscObjectComposedDataMax; 133 void **new_ar; 134 PetscObjectState *new_ir; 135 136 PetscFunctionBegin; 137 PetscAssert(n >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of composed star data ids: %" PetscInt_FMT " < 0", n); 138 PetscCall(PetscCalloc2(new_n, &new_ar, new_n, &new_ir)); 139 PetscCall(PetscMemcpy(new_ar, ar, n * obj_size)); 140 PetscCall(PetscArraycpy(new_ir, ir, n)); 141 PetscCall(PetscFree2(ar, ir)); 142 *id_max = new_n; 143 *composed = new_ar; 144 *composed_state = new_ir; 145 PetscFunctionReturn(PETSC_SUCCESS); 146 } 147 148 #define PetscObjectComposedDataStarIncrease(id_max, composed, composed_state) PetscObjectComposedDataStarIncrease_(id_max, (void ***)(composed), composed_state, sizeof(**(composed))) 149 150 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj) 151 { 152 PetscFunctionBegin; 153 PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate)); 154 PetscFunctionReturn(PETSC_SUCCESS); 155 } 156 157 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj) 158 { 159 PetscFunctionBegin; 160 PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate)); 161 PetscFunctionReturn(PETSC_SUCCESS); 162 } 163 164 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj) 165 { 166 PetscFunctionBegin; 167 PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate)); 168 PetscFunctionReturn(PETSC_SUCCESS); 169 } 170 171 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj) 172 { 173 PetscFunctionBegin; 174 PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate)); 175 PetscFunctionReturn(PETSC_SUCCESS); 176 } 177 178 PetscErrorCode PetscObjectComposedDataIncreaseScalar(PetscObject obj) 179 { 180 PetscFunctionBegin; 181 #if PetscDefined(USE_COMPLEX) 182 PetscCall(PetscObjectComposedDataIncrease(&obj->scalar_idmax, &obj->scalarcomposeddata, &obj->scalarcomposedstate)); 183 #else 184 PetscCall(PetscObjectComposedDataIncreaseReal(obj)); 185 #endif 186 PetscFunctionReturn(PETSC_SUCCESS); 187 } 188 189 PetscErrorCode PetscObjectComposedDataIncreaseScalarstar(PetscObject obj) 190 { 191 PetscFunctionBegin; 192 #if PetscDefined(USE_COMPLEX) 193 PetscCall(PetscObjectComposedDataStarIncrease(&obj->scalarstar_idmax, &obj->scalarstarcomposeddata, &obj->scalarstarcomposedstate)); 194 #else 195 PetscCall(PetscObjectComposedDataIncreaseRealstar(obj)); 196 #endif 197 PetscFunctionReturn(PETSC_SUCCESS); 198 } 199 200 /*@ 201 PetscObjectGetId - get a unique object ID for the `PetscObject` 202 203 Not Collective 204 205 Input Parameter: 206 . obj - object 207 208 Output Parameter: 209 . id - integer ID 210 211 Level: developer 212 213 Note: 214 The object ID may be different on different processes, but object IDs are never reused so local equality implies global equality. 215 216 .seealso: `PetscObjectStateGet()`, `PetscObjectCompareId()` 217 @*/ 218 PetscErrorCode PetscObjectGetId(PetscObject obj, PetscObjectId *id) 219 { 220 PetscFunctionBegin; 221 PetscValidHeader(obj, 1); 222 PetscAssertPointer(id, 2); 223 *id = obj->id; 224 PetscFunctionReturn(PETSC_SUCCESS); 225 } 226 227 /*@ 228 PetscObjectCompareId - compares the objects ID with a given id 229 230 Not Collective 231 232 Input Parameters: 233 + obj - object 234 - id - integer ID 235 236 Output Parameter: 237 . eq - the ids are equal 238 239 Level: developer 240 241 Note: 242 The object ID may be different on different processes, but object IDs are never reused so 243 local equality implies global equality. 244 245 .seealso: `PetscObjectStateGet()`, `PetscObjectGetId()` 246 @*/ 247 PetscErrorCode PetscObjectCompareId(PetscObject obj, PetscObjectId id, PetscBool *eq) 248 { 249 PetscObjectId oid; 250 251 PetscFunctionBegin; 252 PetscValidHeader(obj, 1); 253 PetscAssertPointer(eq, 3); 254 PetscCall(PetscObjectGetId(obj, &oid)); 255 *eq = (id == oid) ? PETSC_TRUE : PETSC_FALSE; 256 PetscFunctionReturn(PETSC_SUCCESS); 257 } 258