1 #include <petsc/private/petscimpl.h> 2 #include <petsc/private/bagimpl.h> /*I "petscbag.h" I*/ 3 #include <petscviewer.h> 4 5 /* 6 Adds item to the linked list in a bag 7 */ 8 static PetscErrorCode PetscBagRegister_Private(PetscBag bag, PetscBagItem item, const char *name, const char *help) 9 { 10 PetscFunctionBegin; 11 PetscCall(PetscStrncpy(item->name, name, PETSC_BAG_NAME_LENGTH - 1)); 12 PetscCall(PetscStrncpy(item->help, help, PETSC_BAG_HELP_LENGTH - 1)); 13 if (bag->bagitems) { 14 PetscBagItem nitem = bag->bagitems; 15 16 while (nitem->next) nitem = nitem->next; 17 nitem->next = item; 18 } else bag->bagitems = item; 19 bag->count++; 20 PetscFunctionReturn(PETSC_SUCCESS); 21 } 22 23 /*@C 24 PetscBagRegisterEnum - add an enum value to a `PetscBag` 25 26 Logically Collective 27 28 Input Parameters: 29 + bag - the bag of values 30 . addr - location of enum in struct, for example `¶ms->dt` 31 . list - array of strings containing names of enum values followed by enum name followed by enum prefix 32 . mdefault - the initial value, cast with (`PetscEnum`) 33 . name - the name of the item 34 - help - longer string with more information about the value 35 36 Level: beginner 37 38 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 39 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 40 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 41 @*/ 42 PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help) 43 { 44 PetscBagItem item; 45 char nname[PETSC_BAG_NAME_LENGTH + 1]; 46 PetscBool printhelp; 47 PetscInt i = 0; 48 49 PetscFunctionBegin; 50 PetscAssertPointer(bag, 1); 51 PetscAssertPointer(addr, 2); 52 PetscAssertPointer(list, 3); 53 PetscAssertPointer(name, 5); 54 PetscAssertPointer(help, 6); 55 nname[0] = '-'; 56 nname[1] = 0; 57 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 58 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 59 if (printhelp) { 60 while (list[i++]); 61 PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help)); 62 for (i = 0; list[i + 2]; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " %s", list[i])); 63 PetscCall((*PetscHelpPrintf)(bag->bagcomm, "\n")); 64 } 65 PetscCall(PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL)); 66 67 PetscCall(PetscNew(&item)); 68 item->dtype = PETSC_ENUM; 69 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 70 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 71 item->next = NULL; 72 item->msize = 1; 73 PetscCall(PetscStrArrayallocpy(list, &item->list)); 74 *(PetscEnum *)addr = mdefault; 75 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 76 PetscFunctionReturn(PETSC_SUCCESS); 77 } 78 79 /*@C 80 PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag` 81 82 Logically Collective 83 84 Input Parameters: 85 + bag - the bag of values 86 . addr - location of integer in struct, for example `¶ms->i` 87 . msize - number of entries in array 88 . name - name of the array 89 - help - longer string with more information about the value 90 91 Level: beginner 92 93 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 94 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 95 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 96 @*/ 97 PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help) 98 { 99 PetscBagItem item; 100 char nname[PETSC_BAG_NAME_LENGTH + 1]; 101 PetscBool printhelp; 102 PetscInt i, tmp = msize; 103 104 PetscFunctionBegin; 105 PetscAssertPointer(bag, 1); 106 PetscAssertPointer(addr, 2); 107 PetscAssertPointer(name, 4); 108 PetscAssertPointer(help, 5); 109 nname[0] = '-'; 110 nname[1] = 0; 111 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 112 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 113 if (printhelp) { 114 PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name)); 115 for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i)); 116 PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help)); 117 } 118 PetscCall(PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, (PetscInt *)addr, &tmp, NULL)); 119 120 PetscCall(PetscNew(&item)); 121 item->dtype = PETSC_INT; 122 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 123 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 124 item->next = NULL; 125 item->msize = msize; 126 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 127 PetscFunctionReturn(PETSC_SUCCESS); 128 } 129 130 /*@C 131 PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag` 132 133 Logically Collective 134 135 Input Parameters: 136 + bag - the bag of values 137 . addr - location of real array in struct, for example `¶ms->d` 138 . msize - number of entries in the array 139 . name - name of the array 140 - help - longer string with more information about the value 141 142 Level: beginner 143 144 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 145 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 146 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 147 @*/ 148 PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help) 149 { 150 PetscBagItem item; 151 char nname[PETSC_BAG_NAME_LENGTH + 1]; 152 PetscBool printhelp; 153 PetscInt i, tmp = msize; 154 155 PetscFunctionBegin; 156 PetscAssertPointer(bag, 1); 157 PetscAssertPointer(addr, 2); 158 PetscAssertPointer(name, 4); 159 PetscAssertPointer(help, 5); 160 nname[0] = '-'; 161 nname[1] = 0; 162 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 163 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 164 if (printhelp) { 165 PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name)); 166 for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)(*((PetscReal *)addr) + i))); 167 PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help)); 168 } 169 PetscCall(PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, (PetscReal *)addr, &tmp, NULL)); 170 171 PetscCall(PetscNew(&item)); 172 item->dtype = PETSC_REAL; 173 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 174 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 175 item->next = NULL; 176 item->msize = msize; 177 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 178 PetscFunctionReturn(PETSC_SUCCESS); 179 } 180 181 /*@C 182 PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag` 183 184 Logically Collective 185 186 Input Parameters: 187 + bag - the bag of values 188 . addr - location of integer in struct, for example `¶ms->i` 189 . mdefault - the initial value 190 . name - name of the integer 191 - help - longer string with more information about the value 192 193 Level: beginner 194 195 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 196 `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 197 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 198 @*/ 199 PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help) 200 { 201 PetscBagItem item; 202 char nname[PETSC_BAG_NAME_LENGTH + 1]; 203 PetscBool printhelp; 204 205 PetscFunctionBegin; 206 PetscAssertPointer(bag, 1); 207 PetscAssertPointer(addr, 2); 208 PetscAssertPointer(name, 4); 209 PetscAssertPointer(help, 5); 210 nname[0] = '-'; 211 nname[1] = 0; 212 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 213 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 214 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help)); 215 PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL)); 216 217 PetscCall(PetscNew(&item)); 218 item->dtype = PETSC_INT; 219 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 220 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 221 item->next = NULL; 222 item->msize = 1; 223 *(PetscInt *)addr = mdefault; 224 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 225 PetscFunctionReturn(PETSC_SUCCESS); 226 } 227 228 /*@C 229 PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag` 230 231 Logically Collective 232 233 Input Parameters: 234 + bag - the bag of values 235 . addr - location of integer in struct, for example `¶ms->i` 236 . mdefault - the initial value 237 . name - name of the integer 238 - help - longer string with more information about the value 239 240 Level: beginner 241 242 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 243 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 244 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 245 @*/ 246 PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help) 247 { 248 PetscBagItem item; 249 char nname[PETSC_BAG_NAME_LENGTH + 1]; 250 PetscBool printhelp; 251 PetscInt odefault; 252 PetscBool flg; 253 254 PetscFunctionBegin; 255 nname[0] = '-'; 256 nname[1] = 0; 257 258 PetscCall(PetscIntCast(mdefault, &odefault)); 259 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 260 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 261 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help)); 262 PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg)); 263 if (flg) mdefault = odefault; 264 265 PetscCall(PetscNew(&item)); 266 item->dtype = PETSC_INT; 267 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 268 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 269 item->next = NULL; 270 item->msize = 1; 271 *(PetscInt64 *)addr = mdefault; 272 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 273 PetscFunctionReturn(PETSC_SUCCESS); 274 } 275 276 /*@C 277 PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag` 278 279 Logically Collective 280 281 Input Parameters: 282 + bag - the bag of values 283 . addr - location of boolean array in struct, for example `¶ms->b` 284 . msize - number of entries in array 285 . name - name of the boolean array 286 - help - longer string with more information about the value 287 288 Level: beginner 289 290 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 291 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 292 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 293 @*/ 294 PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help) 295 { 296 PetscBagItem item; 297 char nname[PETSC_BAG_NAME_LENGTH + 1]; 298 PetscBool printhelp; 299 PetscInt i, tmp = msize; 300 301 PetscFunctionBegin; 302 PetscAssertPointer(bag, 1); 303 PetscAssertPointer(addr, 2); 304 PetscAssertPointer(name, 4); 305 PetscAssertPointer(help, 5); 306 nname[0] = '-'; 307 nname[1] = 0; 308 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 309 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 310 if (printhelp) { 311 PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name)); 312 for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i)); 313 PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help)); 314 } 315 PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, (PetscBool *)addr, &tmp, NULL)); 316 317 PetscCall(PetscNew(&item)); 318 item->dtype = PETSC_BOOL; 319 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 320 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 321 item->next = NULL; 322 item->msize = msize; 323 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 324 PetscFunctionReturn(PETSC_SUCCESS); 325 } 326 327 /*@C 328 PetscBagRegisterString - add a string value to a `PetscBag` 329 330 Logically Collective 331 332 Input Parameters: 333 + bag - the bag of values 334 . addr - location of start of string in struct, for example `¶ms->mystring` 335 . msize - length of the string space in the struct 336 . mdefault - the initial value 337 . name - name of the string 338 - help - longer string with more information about the value 339 340 Level: beginner 341 342 Note: 343 The struct must have the field char mystring[`msize`]; not char *mystring 344 345 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 346 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 347 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 348 @*/ 349 PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help) PeNS 350 { 351 PetscBagItem item; 352 char nname[PETSC_BAG_NAME_LENGTH + 1]; 353 PetscBool printhelp; 354 355 PetscFunctionBegin; 356 PetscAssertPointer(bag, 1); 357 PetscAssertPointer(addr, 2); 358 PetscAssertPointer(mdefault, 4); 359 PetscAssertPointer(name, 5); 360 PetscAssertPointer(help, 6); 361 nname[0] = '-'; 362 nname[1] = 0; 363 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 364 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 365 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help)); 366 367 PetscCall(PetscNew(&item)); 368 item->dtype = PETSC_CHAR; 369 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 370 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 371 item->next = NULL; 372 item->msize = msize; 373 if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1)); 374 PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL)); 375 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 376 PetscFunctionReturn(PETSC_SUCCESS); 377 } 378 379 /*@C 380 PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag` 381 382 Logically Collective 383 384 Input Parameters: 385 + bag - the bag of values 386 . addr - location of `PetscReal` in struct, for example `¶ms->r` 387 . mdefault - the initial value 388 . name - name of the variable 389 - help - longer string with more information about the value 390 391 Level: beginner 392 393 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 394 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 395 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 396 @*/ 397 PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help) 398 { 399 PetscBagItem item; 400 char nname[PETSC_BAG_NAME_LENGTH + 1]; 401 PetscBool printhelp; 402 403 PetscFunctionBegin; 404 PetscAssertPointer(bag, 1); 405 PetscAssertPointer(addr, 2); 406 PetscAssertPointer(name, 4); 407 PetscAssertPointer(help, 5); 408 nname[0] = '-'; 409 nname[1] = 0; 410 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 411 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 412 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help)); 413 PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL)); 414 415 PetscCall(PetscNew(&item)); 416 item->dtype = PETSC_REAL; 417 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 418 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 419 item->next = NULL; 420 item->msize = 1; 421 *(PetscReal *)addr = mdefault; 422 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 423 PetscFunctionReturn(PETSC_SUCCESS); 424 } 425 426 /*@C 427 PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag` 428 429 Logically Collective 430 431 Input Parameters: 432 + bag - the bag of values 433 . addr - location of `PetscScalar` in struct, for example `¶ms->c` 434 . mdefault - the initial value 435 . name - name of the variable 436 - help - longer string with more information about the value 437 438 Level: beginner 439 440 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 441 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagSetFromOptions()`, 442 `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 443 @*/ 444 PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help) 445 { 446 PetscBagItem item; 447 char nname[PETSC_BAG_NAME_LENGTH + 1]; 448 PetscBool printhelp; 449 450 PetscFunctionBegin; 451 PetscAssertPointer(bag, 1); 452 PetscAssertPointer(addr, 2); 453 PetscAssertPointer(name, 4); 454 PetscAssertPointer(help, 5); 455 nname[0] = '-'; 456 nname[1] = 0; 457 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 458 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 459 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help)); 460 PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL)); 461 462 PetscCall(PetscNew(&item)); 463 item->dtype = PETSC_SCALAR; 464 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 465 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 466 item->next = NULL; 467 item->msize = 1; 468 *(PetscScalar *)addr = mdefault; 469 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 470 PetscFunctionReturn(PETSC_SUCCESS); 471 } 472 473 /*@C 474 PetscBagRegisterBool - add a `PetscBool` to a `PetscBag` 475 476 Logically Collective 477 478 Input Parameters: 479 + bag - the bag of values 480 . addr - location of `PetscBool` in struct, for example `¶ms->b` 481 . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE` 482 . name - name of the variable 483 - help - longer string with more information about the value 484 485 Level: beginner 486 487 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 488 `PetscBagRegisterInt()`, `PetscBagRegisterScalar()` 489 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 490 @*/ 491 PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help) 492 { 493 PetscBagItem item; 494 char nname[PETSC_BAG_NAME_LENGTH + 1]; 495 PetscBool printhelp; 496 497 PetscFunctionBegin; 498 PetscAssertPointer(bag, 1); 499 PetscAssertPointer(addr, 2); 500 PetscAssertPointer(name, 4); 501 PetscAssertPointer(help, 5); 502 nname[0] = '-'; 503 nname[1] = 0; 504 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 505 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 506 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help)); 507 PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL)); 508 509 PetscCall(PetscNew(&item)); 510 item->dtype = PETSC_BOOL; 511 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 512 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 513 item->next = NULL; 514 item->msize = 1; 515 *(PetscBool *)addr = mdefault; 516 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 517 PetscFunctionReturn(PETSC_SUCCESS); 518 } 519 520 /*@ 521 PetscBagDestroy - Destroys a `PetscBag` 522 523 Collective 524 525 Input Parameter: 526 . bag - the bag of values 527 528 Level: beginner 529 530 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 531 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 532 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 533 @*/ 534 PetscErrorCode PetscBagDestroy(PetscBag *bag) 535 { 536 PetscBagItem nitem; 537 538 PetscFunctionBegin; 539 if (!*bag) PetscFunctionReturn(PETSC_SUCCESS); 540 PetscAssertPointer(*bag, 1); 541 nitem = (*bag)->bagitems; 542 while (nitem) { 543 PetscBagItem item = nitem->next; 544 545 if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list)); 546 PetscCall(PetscFree(nitem)); 547 nitem = item; 548 } 549 if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix)); 550 PetscCall(PetscFree(*bag)); 551 PetscFunctionReturn(PETSC_SUCCESS); 552 } 553 554 /*@ 555 PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database 556 557 Collective 558 559 Input Parameter: 560 . bag - the bag of values 561 562 Level: beginner 563 564 Note: 565 The options database keys for the entries are of the form `-[bagprefix]_name value` 566 567 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 568 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 569 `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()` 570 @*/ 571 PetscErrorCode PetscBagSetFromOptions(PetscBag bag) 572 { 573 PetscBagItem nitem = bag->bagitems; 574 char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3]; 575 PetscInt n; 576 577 PetscFunctionBegin; 578 PetscAssertPointer(bag, 1); 579 PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname))); 580 PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname))); 581 PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname))); 582 PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL); 583 while (nitem) { 584 name[0] = '-'; 585 name[1] = 0; 586 PetscCall(PetscStrlcat(name, nitem->name, sizeof(name))); 587 if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */ 588 char *value = ((char *)bag) + nitem->offset; 589 PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL)); 590 } else if (nitem->dtype == PETSC_REAL) { 591 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 592 if (nitem->msize == 1) { 593 PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL)); 594 } else { 595 n = nitem->msize; 596 PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL)); 597 } 598 } else if (nitem->dtype == PETSC_SCALAR) { 599 PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset); 600 PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL)); 601 } else if (nitem->dtype == PETSC_INT) { 602 PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset); 603 if (nitem->msize == 1) { 604 PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL)); 605 } else { 606 n = nitem->msize; 607 PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL)); 608 } 609 } else if (nitem->dtype == PETSC_ENUM) { 610 PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset); 611 PetscInt i = 0; 612 while (nitem->list[i++]); 613 PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL)); 614 } else if (nitem->dtype == PETSC_BOOL) { 615 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 616 if (nitem->msize == 1) { 617 PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL)); 618 } else { 619 n = nitem->msize; 620 PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL)); 621 } 622 } 623 nitem = nitem->next; 624 } 625 PetscOptionsEnd(); 626 PetscFunctionReturn(PETSC_SUCCESS); 627 } 628 629 /*@ 630 PetscBagView - Views a bag of values as either ASCII text or a binary file 631 632 Collective 633 634 Input Parameters: 635 + bag - the bag of values 636 - view - location to view the values 637 638 Level: beginner 639 640 Note: 641 Currently PETSc bags saved in a binary file can only be read back 642 in on a machine with the same binary format. 643 644 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 645 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 646 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 647 @*/ 648 PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view) 649 { 650 PetscBool isascii, isbinary; 651 PetscBagItem nitem = bag->bagitems; 652 653 PetscFunctionBegin; 654 PetscAssertPointer(bag, 1); 655 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2); 656 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 657 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 658 if (isascii) { 659 if (bag->bagprefix) { 660 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp)); 661 } else { 662 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp)); 663 } 664 while (nitem) { 665 if (nitem->dtype == PETSC_CHAR) { 666 char *value = ((char *)bag) + nitem->offset; 667 char tmp = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */ 668 value[nitem->msize - 1] = 0; 669 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help)); 670 value[nitem->msize - 1] = tmp; 671 } else if (nitem->dtype == PETSC_REAL) { 672 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 673 PetscInt i; 674 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 675 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i])); 676 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 677 } else if (nitem->dtype == PETSC_SCALAR) { 678 PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset); 679 #if defined(PETSC_USE_COMPLEX) 680 if ((double)PetscImaginaryPart(value)) { 681 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help)); 682 } else { 683 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help)); 684 } 685 #else 686 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)value, nitem->help)); 687 #endif 688 } else if (nitem->dtype == PETSC_INT) { 689 PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset); 690 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 691 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i])); 692 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 693 } else if (nitem->dtype == PETSC_BOOL) { 694 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 695 PetscInt i; 696 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 697 for (i = 0; i < nitem->msize; i++) { 698 /* stdbool.h defines true=1 and false=0, but non-conformant Fortran compilers define .true.=0xff (-1 if signed, 255 if unsigned). 699 with the checks for either PETSC_FALSE or PETSC_TRUE we truly demand that the value be 0 or 1 */ 700 PetscCheck(value[i] == PETSC_FALSE || value[i] == PETSC_TRUE, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Boolean value for %s %s is corrupt; integer value %" PetscInt_FMT, nitem->name, nitem->help, (PetscInt)value[i]); 701 PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]])); 702 } 703 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 704 } else if (nitem->dtype == PETSC_ENUM) { 705 PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset); 706 PetscInt i = 0; 707 while (nitem->list[i++]); 708 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help)); 709 } 710 nitem = nitem->next; 711 } 712 } else if (isbinary) { 713 PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype; 714 PetscInt deprecatedbagsize = 0; 715 PetscViewerFormat format; 716 PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT)); 717 PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT)); 718 PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT)); 719 PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 720 PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 721 while (nitem) { 722 PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT)); 723 dtype = (PetscInt)nitem->dtype; 724 PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT)); 725 PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 726 PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 727 PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT)); 728 729 PetscCall(PetscViewerBinaryWrite(view, (char *)bag + nitem->offset, nitem->msize, nitem->dtype)); 730 if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list)); 731 nitem = nitem->next; 732 } 733 PetscCall(PetscViewerGetFormat(view, &format)); 734 if (format == PETSC_VIEWER_BINARY_MATLAB) { 735 MPI_Comm comm; 736 FILE *info; 737 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 738 PetscCall(PetscViewerBinaryGetInfoPointer(view, &info)); 739 PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n")); 740 PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname)); 741 PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n")); 742 } 743 } 744 PetscFunctionReturn(PETSC_SUCCESS); 745 } 746 747 /*@ 748 PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed. 749 750 Collective 751 752 Input Parameters: 753 + bag - the object 754 . bobj - optional other object that provides prefix (if `NULL` then the prefix in obj is used) 755 - optionname - option to activate viewing 756 757 Level: intermediate 758 759 .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer` 760 @*/ 761 PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[]) 762 { 763 static PetscBool incall = PETSC_FALSE; 764 PetscViewer viewer; 765 PetscViewerFormat format; 766 const char *prefix, *bprefix = NULL; 767 PetscBool flg; 768 769 PetscFunctionBegin; 770 if (incall) PetscFunctionReturn(PETSC_SUCCESS); 771 incall = PETSC_TRUE; 772 PetscAssertPointer(bag, 1); 773 if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix)); 774 prefix = bobj ? bprefix : bag->bagprefix; 775 PetscCall(PetscOptionsCreateViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg)); 776 if (flg) { 777 PetscCall(PetscViewerPushFormat(viewer, format)); 778 PetscCall(PetscBagView(bag, viewer)); 779 PetscCall(PetscViewerFlush(viewer)); 780 PetscCall(PetscViewerPopFormat(viewer)); 781 PetscCall(PetscViewerDestroy(&viewer)); 782 } 783 incall = PETSC_FALSE; 784 PetscFunctionReturn(PETSC_SUCCESS); 785 } 786 787 /*@ 788 PetscBagLoad - Loads a bag of values from a binary file 789 790 Collective 791 792 Input Parameters: 793 + view - file to load values from 794 - bag - the bag of values 795 796 Level: beginner 797 798 Note: 799 You must have created and registered all the fields in the bag before loading into it. This only loads values. 800 801 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()` 802 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 803 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 804 @*/ 805 PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag) 806 { 807 PetscBool isbinary; 808 PetscInt classid, bagcount, dtype, msize, offset, deprecatedbagsize; 809 char name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list; 810 PetscBagItem nitem; 811 MPI_Comm comm; 812 PetscMPIInt flag; 813 814 PetscFunctionBegin; 815 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1); 816 PetscAssertPointer(bag, 2); 817 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 818 PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag)); 819 PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag"); 820 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 821 PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type"); 822 823 PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT)); 824 PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file"); 825 PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT)); 826 PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT)); 827 PetscCheck(bagcount == bag->count, comm, PETSC_ERR_ARG_INCOMP, "Bag in file has different number of entries %" PetscInt_FMT " then passed in bag %" PetscInt_FMT, bagcount, bag->count); 828 PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 829 PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 830 831 nitem = bag->bagitems; 832 for (PetscInt i = 0; i < bagcount; i++) { 833 PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT)); 834 /* ignore the offset in the file */ 835 PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT)); 836 PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 837 PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 838 PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT)); 839 840 if (dtype == (PetscInt)PETSC_CHAR) { 841 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR)); 842 } else if (dtype == (PetscInt)PETSC_REAL) { 843 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL)); 844 } else if (dtype == (PetscInt)PETSC_SCALAR) { 845 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR)); 846 } else if (dtype == (PetscInt)PETSC_INT) { 847 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT)); 848 } else if (dtype == (PetscInt)PETSC_BOOL) { 849 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL)); 850 } else if (dtype == (PetscInt)PETSC_ENUM) { 851 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM)); 852 PetscCall(PetscViewerBinaryReadStringArray(view, &list)); 853 /* don't need to save list because it is already registered in the bag */ 854 PetscCall(PetscFree(list)); 855 } 856 nitem = nitem->next; 857 } 858 PetscFunctionReturn(PETSC_SUCCESS); 859 } 860 861 /*@C 862 PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files, 863 can have values set from the options database 864 865 Collective 866 867 Input Parameters: 868 + comm - communicator to share bag 869 - bagsize - size of the C structure holding the values, for example `sizeof(mystruct)` 870 871 Output Parameter: 872 . bag - the bag of values 873 874 Level: intermediate 875 876 Notes: 877 After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout 878 879 The size of the struct must be small enough to fit in a `PetscInt`; by default 880 `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length. 881 The warning about casting to a shorter length can be ignored below unless your struct is too large 882 883 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 884 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 885 `PetscBagSetFromOptions()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 886 @*/ 887 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag) 888 { 889 const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar); 890 891 PetscFunctionBegin; 892 PetscAssertPointer(bag, 3); 893 894 PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize)); 895 PetscCall(PetscCalloc(totalsize, bag)); 896 PetscCall(PetscIntCast(totalsize, &(*bag)->bagsize)); 897 (*bag)->bagcomm = comm; 898 (*bag)->bagprefix = NULL; 899 (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar)); 900 PetscFunctionReturn(PETSC_SUCCESS); 901 } 902 903 /*@ 904 PetscBagSetName - Sets the name of a bag of values 905 906 Not Collective 907 908 Level: intermediate 909 910 Input Parameters: 911 + bag - the bag of values 912 . name - the name assigned to the bag 913 - help - help message for bag 914 915 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 916 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 917 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 918 @*/ 919 PetscErrorCode PetscBagSetName(PetscBag bag, const char name[], const char help[]) 920 { 921 PetscFunctionBegin; 922 PetscAssertPointer(bag, 1); 923 PetscAssertPointer(name, 2); 924 PetscAssertPointer(help, 3); 925 PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1)); 926 PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1)); 927 PetscFunctionReturn(PETSC_SUCCESS); 928 } 929 930 /*@C 931 PetscBagGetName - Gets the name of a bag of values 932 933 Not Collective 934 935 Level: intermediate 936 937 Input Parameter: 938 . bag - the bag of values 939 940 Output Parameter: 941 . name - the name assigned to the bag 942 943 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 944 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 945 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 946 @*/ 947 PetscErrorCode PetscBagGetName(PetscBag bag, const char **name) 948 { 949 PetscFunctionBegin; 950 PetscAssertPointer(bag, 1); 951 PetscAssertPointer(name, 2); 952 *name = bag->bagname; 953 PetscFunctionReturn(PETSC_SUCCESS); 954 } 955 956 /*@C 957 PetscBagGetData - Gives back the user - access to memory that 958 can be used for storing user-data-structure 959 960 Not Collective 961 962 Input Parameter: 963 . bag - the bag of values 964 965 Output Parameter: 966 . data - pointer to memory that will have user-data-structure, this can be cast to a pointer of the type the C struct used in 967 defining the bag 968 969 Level: intermediate 970 971 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()` 972 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 973 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 974 @*/ 975 PetscErrorCode PetscBagGetData(PetscBag bag, PetscCtxRt data) 976 { 977 PetscFunctionBegin; 978 PetscAssertPointer(bag, 1); 979 PetscAssertPointer(data, 2); 980 *(void **)data = bag->structlocation; 981 PetscFunctionReturn(PETSC_SUCCESS); 982 } 983 984 /*@ 985 PetscBagSetOptionsPrefix - Sets the prefix used for searching for all 986 `PetscBag` items in the options database. 987 988 Logically Collective 989 990 Level: intermediate 991 992 Input Parameters: 993 + bag - the bag of values 994 - pre - the prefix to prepend all Bag item names with. 995 996 Note: 997 Must be called prior to registering any of the bag items. 998 999 .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 1000 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 1001 @*/ 1002 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[]) 1003 { 1004 PetscFunctionBegin; 1005 PetscAssertPointer(bag, 1); 1006 if (pre) { 1007 PetscAssertPointer(pre, 2); 1008 PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 1009 PetscCall(PetscFree(bag->bagprefix)); 1010 PetscCall(PetscStrallocpy(pre, &bag->bagprefix)); 1011 } else PetscCall(PetscFree(bag->bagprefix)); 1012 PetscFunctionReturn(PETSC_SUCCESS); 1013 } 1014 1015 /*@C 1016 PetscBagGetNames - Get the names of all entries in the bag 1017 1018 Not Collective 1019 1020 Input Parameter: 1021 . bag - the bag of values 1022 1023 Output Parameter: 1024 . names - pass in an array of char pointers to hold the names. The array must be as long as the number of items in the bag. 1025 1026 Level: intermediate 1027 1028 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()` 1029 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 1030 @*/ 1031 PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[]) 1032 { 1033 PetscBagItem nitem = bag->bagitems; 1034 1035 PetscFunctionBegin; 1036 PetscAssertPointer(bag, 1); 1037 PetscAssertPointer(names, 2); 1038 for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name; 1039 PetscFunctionReturn(PETSC_SUCCESS); 1040 } 1041