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 /*@C 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 @*/ 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 /*@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 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 @*/ 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 @*/ 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 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; 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 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 149 PetscErrorCode PetscObjectComposedDataIncreaseInt(PetscObject obj) 150 { 151 PetscFunctionBegin; 152 PetscCall(PetscObjectComposedDataIncrease(&obj->int_idmax, &obj->intcomposeddata, &obj->intcomposedstate)); 153 PetscFunctionReturn(PETSC_SUCCESS); 154 } 155 156 PetscErrorCode PetscObjectComposedDataIncreaseIntstar(PetscObject obj) 157 { 158 PetscFunctionBegin; 159 PetscCall(PetscObjectComposedDataStarIncrease(&obj->intstar_idmax, &obj->intstarcomposeddata, &obj->intstarcomposedstate)); 160 PetscFunctionReturn(PETSC_SUCCESS); 161 } 162 163 PetscErrorCode PetscObjectComposedDataIncreaseReal(PetscObject obj) 164 { 165 PetscFunctionBegin; 166 PetscCall(PetscObjectComposedDataIncrease(&obj->real_idmax, &obj->realcomposeddata, &obj->realcomposedstate)); 167 PetscFunctionReturn(PETSC_SUCCESS); 168 } 169 170 PetscErrorCode PetscObjectComposedDataIncreaseRealstar(PetscObject obj) 171 { 172 PetscFunctionBegin; 173 PetscCall(PetscObjectComposedDataStarIncrease(&obj->realstar_idmax, &obj->realstarcomposeddata, &obj->realstarcomposedstate)); 174 PetscFunctionReturn(PETSC_SUCCESS); 175 } 176 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 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 @*/ 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 @*/ 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