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 /* some Fortran compilers use -1 as boolean */ 729 if (dtype == PETSC_BOOL && (*(int *)(((char *)bag) + nitem->offset) == -1)) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE; 730 731 PetscCall(PetscViewerBinaryWrite(view, (char *)bag + nitem->offset, nitem->msize, nitem->dtype)); 732 if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list)); 733 nitem = nitem->next; 734 } 735 PetscCall(PetscViewerGetFormat(view, &format)); 736 if (format == PETSC_VIEWER_BINARY_MATLAB) { 737 MPI_Comm comm; 738 FILE *info; 739 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 740 PetscCall(PetscViewerBinaryGetInfoPointer(view, &info)); 741 PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n")); 742 PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname)); 743 PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n")); 744 } 745 } 746 PetscFunctionReturn(PETSC_SUCCESS); 747 } 748 749 /*@ 750 PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed. 751 752 Collective 753 754 Input Parameters: 755 + bag - the object 756 . bobj - optional other object that provides prefix (if `NULL` then the prefix in obj is used) 757 - optionname - option to activate viewing 758 759 Level: intermediate 760 761 .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer` 762 @*/ 763 PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[]) 764 { 765 static PetscBool incall = PETSC_FALSE; 766 PetscViewer viewer; 767 PetscViewerFormat format; 768 const char *prefix, *bprefix = NULL; 769 PetscBool flg; 770 771 PetscFunctionBegin; 772 if (incall) PetscFunctionReturn(PETSC_SUCCESS); 773 incall = PETSC_TRUE; 774 PetscAssertPointer(bag, 1); 775 if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix)); 776 prefix = bobj ? bprefix : bag->bagprefix; 777 PetscCall(PetscOptionsCreateViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg)); 778 if (flg) { 779 PetscCall(PetscViewerPushFormat(viewer, format)); 780 PetscCall(PetscBagView(bag, viewer)); 781 PetscCall(PetscViewerFlush(viewer)); 782 PetscCall(PetscViewerPopFormat(viewer)); 783 PetscCall(PetscViewerDestroy(&viewer)); 784 } 785 incall = PETSC_FALSE; 786 PetscFunctionReturn(PETSC_SUCCESS); 787 } 788 789 /*@ 790 PetscBagLoad - Loads a bag of values from a binary file 791 792 Collective 793 794 Input Parameters: 795 + view - file to load values from 796 - bag - the bag of values 797 798 Level: beginner 799 800 Note: 801 You must have created and registered all the fields in the bag before loading into it. This only loads values. 802 803 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()` 804 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 805 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 806 @*/ 807 PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag) 808 { 809 PetscBool isbinary; 810 PetscInt classid, bagcount, dtype, msize, offset, deprecatedbagsize; 811 char name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list; 812 PetscBagItem nitem; 813 MPI_Comm comm; 814 PetscMPIInt flag; 815 816 PetscFunctionBegin; 817 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1); 818 PetscAssertPointer(bag, 2); 819 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 820 PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag)); 821 PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag"); 822 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 823 PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type"); 824 825 PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT)); 826 PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file"); 827 PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT)); 828 PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT)); 829 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); 830 PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 831 PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 832 833 nitem = bag->bagitems; 834 for (PetscInt i = 0; i < bagcount; i++) { 835 PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT)); 836 /* ignore the offset in the file */ 837 PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT)); 838 PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 839 PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 840 PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT)); 841 842 if (dtype == (PetscInt)PETSC_CHAR) { 843 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR)); 844 } else if (dtype == (PetscInt)PETSC_REAL) { 845 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL)); 846 } else if (dtype == (PetscInt)PETSC_SCALAR) { 847 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR)); 848 } else if (dtype == (PetscInt)PETSC_INT) { 849 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT)); 850 } else if (dtype == (PetscInt)PETSC_BOOL) { 851 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL)); 852 } else if (dtype == (PetscInt)PETSC_ENUM) { 853 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM)); 854 PetscCall(PetscViewerBinaryReadStringArray(view, &list)); 855 /* don't need to save list because it is already registered in the bag */ 856 PetscCall(PetscFree(list)); 857 } 858 nitem = nitem->next; 859 } 860 PetscFunctionReturn(PETSC_SUCCESS); 861 } 862 863 /*@C 864 PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files, 865 can have values set from the options database 866 867 Collective 868 869 Input Parameters: 870 + comm - communicator to share bag 871 - bagsize - size of the C structure holding the values, for example `sizeof(mystruct)` 872 873 Output Parameter: 874 . bag - the bag of values 875 876 Level: intermediate 877 878 Notes: 879 After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout 880 881 The size of the struct must be small enough to fit in a `PetscInt`; by default 882 `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length. 883 The warning about casting to a shorter length can be ignored below unless your struct is too large 884 885 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 886 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 887 `PetscBagSetFromOptions()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 888 @*/ 889 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag) 890 { 891 const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar); 892 893 PetscFunctionBegin; 894 PetscAssertPointer(bag, 3); 895 896 PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize)); 897 PetscCall(PetscCalloc(totalsize, bag)); 898 PetscCall(PetscIntCast(totalsize, &(*bag)->bagsize)); 899 (*bag)->bagcomm = comm; 900 (*bag)->bagprefix = NULL; 901 (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar)); 902 PetscFunctionReturn(PETSC_SUCCESS); 903 } 904 905 /*@ 906 PetscBagSetName - Sets the name of a bag of values 907 908 Not Collective 909 910 Level: intermediate 911 912 Input Parameters: 913 + bag - the bag of values 914 . name - the name assigned to the bag 915 - help - help message for bag 916 917 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 918 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 919 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 920 @*/ 921 PetscErrorCode PetscBagSetName(PetscBag bag, const char name[], const char help[]) 922 { 923 PetscFunctionBegin; 924 PetscAssertPointer(bag, 1); 925 PetscAssertPointer(name, 2); 926 PetscAssertPointer(help, 3); 927 PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1)); 928 PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1)); 929 PetscFunctionReturn(PETSC_SUCCESS); 930 } 931 932 /*@C 933 PetscBagGetName - Gets the name of a bag of values 934 935 Not Collective 936 937 Level: intermediate 938 939 Input Parameter: 940 . bag - the bag of values 941 942 Output Parameter: 943 . name - the name assigned to the bag 944 945 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 946 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 947 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 948 @*/ 949 PetscErrorCode PetscBagGetName(PetscBag bag, const char **name) 950 { 951 PetscFunctionBegin; 952 PetscAssertPointer(bag, 1); 953 PetscAssertPointer(name, 2); 954 *name = bag->bagname; 955 PetscFunctionReturn(PETSC_SUCCESS); 956 } 957 958 /*@C 959 PetscBagGetData - Gives back the user - access to memory that 960 can be used for storing user-data-structure 961 962 Not Collective 963 964 Input Parameter: 965 . bag - the bag of values 966 967 Output Parameter: 968 . 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 969 defining the bag 970 971 Level: intermediate 972 973 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()` 974 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 975 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 976 @*/ 977 PetscErrorCode PetscBagGetData(PetscBag bag, PeCtx data) 978 { 979 PetscFunctionBegin; 980 PetscAssertPointer(bag, 1); 981 PetscAssertPointer(data, 2); 982 *(void **)data = bag->structlocation; 983 PetscFunctionReturn(PETSC_SUCCESS); 984 } 985 986 /*@ 987 PetscBagSetOptionsPrefix - Sets the prefix used for searching for all 988 `PetscBag` items in the options database. 989 990 Logically Collective 991 992 Level: intermediate 993 994 Input Parameters: 995 + bag - the bag of values 996 - pre - the prefix to prepend all Bag item names with. 997 998 Note: 999 Must be called prior to registering any of the bag items. 1000 1001 .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 1002 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 1003 @*/ 1004 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[]) 1005 { 1006 PetscFunctionBegin; 1007 PetscAssertPointer(bag, 1); 1008 if (pre) { 1009 PetscAssertPointer(pre, 2); 1010 PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 1011 PetscCall(PetscFree(bag->bagprefix)); 1012 PetscCall(PetscStrallocpy(pre, &bag->bagprefix)); 1013 } else PetscCall(PetscFree(bag->bagprefix)); 1014 PetscFunctionReturn(PETSC_SUCCESS); 1015 } 1016 1017 /*@C 1018 PetscBagGetNames - Get the names of all entries in the bag 1019 1020 Not Collective 1021 1022 Input Parameter: 1023 . bag - the bag of values 1024 1025 Output Parameter: 1026 . 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. 1027 1028 Level: intermediate 1029 1030 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()` 1031 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 1032 @*/ 1033 PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[]) 1034 { 1035 PetscBagItem nitem = bag->bagitems; 1036 1037 PetscFunctionBegin; 1038 PetscAssertPointer(bag, 1); 1039 PetscAssertPointer(names, 2); 1040 for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name; 1041 PetscFunctionReturn(PETSC_SUCCESS); 1042 } 1043