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) 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 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 503 PetscCheck(mdefault == PETSC_FALSE || mdefault == PETSC_TRUE, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boolean %s %s must be boolean; integer value %d", name, help, (int)mdefault); 504 nname[0] = '-'; 505 nname[1] = 0; 506 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 507 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 508 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help)); 509 PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL)); 510 511 PetscCall(PetscNew(&item)); 512 item->dtype = PETSC_BOOL; 513 item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag)); 514 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 515 item->next = NULL; 516 item->msize = 1; 517 *(PetscBool *)addr = mdefault; 518 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 519 PetscFunctionReturn(PETSC_SUCCESS); 520 } 521 522 /*@ 523 PetscBagDestroy - Destroys a `PetscBag` 524 525 Collective 526 527 Input Parameter: 528 . bag - the bag of values 529 530 Level: beginner 531 532 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 533 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 534 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 535 @*/ 536 PetscErrorCode PetscBagDestroy(PetscBag *bag) 537 { 538 PetscBagItem nitem; 539 540 PetscFunctionBegin; 541 if (!*bag) PetscFunctionReturn(PETSC_SUCCESS); 542 PetscAssertPointer(*bag, 1); 543 nitem = (*bag)->bagitems; 544 while (nitem) { 545 PetscBagItem item = nitem->next; 546 547 if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list)); 548 PetscCall(PetscFree(nitem)); 549 nitem = item; 550 } 551 if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix)); 552 PetscCall(PetscFree(*bag)); 553 PetscFunctionReturn(PETSC_SUCCESS); 554 } 555 556 /*@ 557 PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database 558 559 Collective 560 561 Input Parameter: 562 . bag - the bag of values 563 564 Level: beginner 565 566 Note: 567 The options database keys for the entries are of the form `-[bagprefix]_name value` 568 569 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 570 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 571 `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()` 572 @*/ 573 PetscErrorCode PetscBagSetFromOptions(PetscBag bag) 574 { 575 PetscBagItem nitem = bag->bagitems; 576 char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3]; 577 PetscInt n; 578 579 PetscFunctionBegin; 580 PetscAssertPointer(bag, 1); 581 PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname))); 582 PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname))); 583 PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname))); 584 PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL); 585 while (nitem) { 586 name[0] = '-'; 587 name[1] = 0; 588 PetscCall(PetscStrlcat(name, nitem->name, sizeof(name))); 589 if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */ 590 char *value = ((char *)bag) + nitem->offset; 591 PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL)); 592 } else if (nitem->dtype == PETSC_REAL) { 593 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 594 if (nitem->msize == 1) { 595 PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL)); 596 } else { 597 n = nitem->msize; 598 PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL)); 599 } 600 } else if (nitem->dtype == PETSC_SCALAR) { 601 PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset); 602 PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL)); 603 } else if (nitem->dtype == PETSC_INT) { 604 PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset); 605 if (nitem->msize == 1) { 606 PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL)); 607 } else { 608 n = nitem->msize; 609 PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL)); 610 } 611 } else if (nitem->dtype == PETSC_ENUM) { 612 PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset); 613 PetscInt i = 0; 614 while (nitem->list[i++]); 615 PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL)); 616 } else if (nitem->dtype == PETSC_BOOL) { 617 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 618 if (nitem->msize == 1) { 619 PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL)); 620 } else { 621 n = nitem->msize; 622 PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL)); 623 } 624 } 625 nitem = nitem->next; 626 } 627 PetscOptionsEnd(); 628 PetscFunctionReturn(PETSC_SUCCESS); 629 } 630 631 /*@ 632 PetscBagView - Views a bag of values as either ASCII text or a binary file 633 634 Collective 635 636 Input Parameters: 637 + bag - the bag of values 638 - view - location to view the values 639 640 Level: beginner 641 642 Note: 643 Currently PETSc bags saved in a binary file can only be read back 644 in on a machine with the same binary format. 645 646 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 647 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 648 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 649 @*/ 650 PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view) 651 { 652 PetscBool isascii, isbinary; 653 PetscBagItem nitem = bag->bagitems; 654 655 PetscFunctionBegin; 656 PetscAssertPointer(bag, 1); 657 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2); 658 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 659 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 660 if (isascii) { 661 if (bag->bagprefix) { 662 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp)); 663 } else { 664 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp)); 665 } 666 while (nitem) { 667 if (nitem->dtype == PETSC_CHAR) { 668 char *value = ((char *)bag) + nitem->offset; 669 char tmp = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */ 670 value[nitem->msize - 1] = 0; 671 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help)); 672 value[nitem->msize - 1] = tmp; 673 } else if (nitem->dtype == PETSC_REAL) { 674 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 675 PetscInt i; 676 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 677 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i])); 678 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 679 } else if (nitem->dtype == PETSC_SCALAR) { 680 PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset); 681 #if defined(PETSC_USE_COMPLEX) 682 if ((double)PetscImaginaryPart(value)) { 683 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help)); 684 } else { 685 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help)); 686 } 687 #else 688 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)value, nitem->help)); 689 #endif 690 } else if (nitem->dtype == PETSC_INT) { 691 PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset); 692 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 693 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i])); 694 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 695 } else if (nitem->dtype == PETSC_BOOL) { 696 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 697 PetscInt i; 698 /* some Fortran compilers use -1 as boolean */ 699 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 700 for (i = 0; i < nitem->msize; i++) { 701 if (((int)value[i]) == -1) value[i] = PETSC_TRUE; 702 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 703 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]); 704 PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]])); 705 } 706 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 707 } else if (nitem->dtype == PETSC_ENUM) { 708 PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset); 709 PetscInt i = 0; 710 while (nitem->list[i++]); 711 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help)); 712 } 713 nitem = nitem->next; 714 } 715 } else if (isbinary) { 716 PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype; 717 PetscInt deprecatedbagsize = 0; 718 PetscViewerFormat format; 719 PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT)); 720 PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT)); 721 PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT)); 722 PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 723 PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 724 while (nitem) { 725 PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT)); 726 dtype = (PetscInt)nitem->dtype; 727 PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT)); 728 PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 729 PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 730 PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT)); 731 /* some Fortran compilers use -1 as boolean */ 732 if (dtype == PETSC_BOOL && (*(int *)(((char *)bag) + nitem->offset) == -1)) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE; 733 734 PetscCall(PetscViewerBinaryWrite(view, (char *)bag + nitem->offset, nitem->msize, nitem->dtype)); 735 if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list)); 736 nitem = nitem->next; 737 } 738 PetscCall(PetscViewerGetFormat(view, &format)); 739 if (format == PETSC_VIEWER_BINARY_MATLAB) { 740 MPI_Comm comm; 741 FILE *info; 742 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 743 PetscCall(PetscViewerBinaryGetInfoPointer(view, &info)); 744 PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n")); 745 PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname)); 746 PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n")); 747 } 748 } 749 PetscFunctionReturn(PETSC_SUCCESS); 750 } 751 752 /*@ 753 PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed. 754 755 Collective 756 757 Input Parameters: 758 + bag - the object 759 . bobj - optional other object that provides prefix (if `NULL` then the prefix in obj is used) 760 - optionname - option to activate viewing 761 762 Level: intermediate 763 764 .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer` 765 @*/ 766 PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[]) 767 { 768 static PetscBool incall = PETSC_FALSE; 769 PetscViewer viewer; 770 PetscViewerFormat format; 771 const char *prefix, *bprefix = NULL; 772 PetscBool flg; 773 774 PetscFunctionBegin; 775 if (incall) PetscFunctionReturn(PETSC_SUCCESS); 776 incall = PETSC_TRUE; 777 PetscAssertPointer(bag, 1); 778 if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix)); 779 prefix = bobj ? bprefix : bag->bagprefix; 780 PetscCall(PetscOptionsCreateViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg)); 781 if (flg) { 782 PetscCall(PetscViewerPushFormat(viewer, format)); 783 PetscCall(PetscBagView(bag, viewer)); 784 PetscCall(PetscViewerFlush(viewer)); 785 PetscCall(PetscViewerPopFormat(viewer)); 786 PetscCall(PetscViewerDestroy(&viewer)); 787 } 788 incall = PETSC_FALSE; 789 PetscFunctionReturn(PETSC_SUCCESS); 790 } 791 792 /*@ 793 PetscBagLoad - Loads a bag of values from a binary file 794 795 Collective 796 797 Input Parameters: 798 + view - file to load values from 799 - bag - the bag of values 800 801 Level: beginner 802 803 Note: 804 You must have created and registered all the fields in the bag before loading into it. This only loads values. 805 806 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()` 807 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 808 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 809 @*/ 810 PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag) 811 { 812 PetscBool isbinary; 813 PetscInt classid, bagcount, dtype, msize, offset, deprecatedbagsize; 814 char name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list; 815 PetscBagItem nitem; 816 MPI_Comm comm; 817 PetscMPIInt flag; 818 819 PetscFunctionBegin; 820 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1); 821 PetscAssertPointer(bag, 2); 822 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 823 PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag)); 824 PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag"); 825 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 826 PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type"); 827 828 PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT)); 829 PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file"); 830 PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT)); 831 PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT)); 832 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); 833 PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 834 PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 835 836 nitem = bag->bagitems; 837 for (PetscInt i = 0; i < bagcount; i++) { 838 PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT)); 839 /* ignore the offset in the file */ 840 PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT)); 841 PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 842 PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 843 PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT)); 844 845 if (dtype == (PetscInt)PETSC_CHAR) { 846 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR)); 847 } else if (dtype == (PetscInt)PETSC_REAL) { 848 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL)); 849 } else if (dtype == (PetscInt)PETSC_SCALAR) { 850 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR)); 851 } else if (dtype == (PetscInt)PETSC_INT) { 852 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT)); 853 } else if (dtype == (PetscInt)PETSC_BOOL) { 854 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL)); 855 } else if (dtype == (PetscInt)PETSC_ENUM) { 856 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM)); 857 PetscCall(PetscViewerBinaryReadStringArray(view, &list)); 858 /* don't need to save list because it is already registered in the bag */ 859 PetscCall(PetscFree(list)); 860 } 861 nitem = nitem->next; 862 } 863 PetscFunctionReturn(PETSC_SUCCESS); 864 } 865 866 /*@C 867 PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files, 868 can have values set from the options database 869 870 Collective 871 872 Input Parameters: 873 + comm - communicator to share bag 874 - bagsize - size of the C structure holding the values, for example sizeof(mystruct) 875 876 Output Parameter: 877 . bag - the bag of values 878 879 Level: intermediate 880 881 Notes: 882 After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout 883 884 The size of the struct must be small enough to fit in a `PetscInt`; by default 885 `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length. 886 The warning about casting to a shorter length can be ignored below unless your struct is too large 887 888 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 889 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 890 `PetscBagSetFromOptions()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 891 @*/ 892 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag) 893 { 894 const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar); 895 896 PetscFunctionBegin; 897 PetscAssertPointer(bag, 3); 898 899 PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize)); 900 PetscCall(PetscCalloc(totalsize, bag)); 901 PetscCall(PetscIntCast(totalsize, &(*bag)->bagsize)); 902 (*bag)->bagcomm = comm; 903 (*bag)->bagprefix = NULL; 904 (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar)); 905 PetscFunctionReturn(PETSC_SUCCESS); 906 } 907 908 /*@ 909 PetscBagSetName - Sets the name of a bag of values 910 911 Not Collective 912 913 Level: intermediate 914 915 Input Parameters: 916 + bag - the bag of values 917 . name - the name assigned to the bag 918 - help - help message for bag 919 920 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 921 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 922 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 923 @*/ 924 PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help) 925 { 926 PetscFunctionBegin; 927 PetscAssertPointer(bag, 1); 928 PetscAssertPointer(name, 2); 929 PetscAssertPointer(help, 3); 930 PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1)); 931 PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1)); 932 PetscFunctionReturn(PETSC_SUCCESS); 933 } 934 935 /*@C 936 PetscBagGetName - Gets the name of a bag of values 937 938 Not Collective 939 940 Level: intermediate 941 942 Input Parameter: 943 . bag - the bag of values 944 945 Output Parameter: 946 . name - the name assigned to the bag 947 948 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 949 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 950 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 951 @*/ 952 PetscErrorCode PetscBagGetName(PetscBag bag, const char **name) 953 { 954 PetscFunctionBegin; 955 PetscAssertPointer(bag, 1); 956 PetscAssertPointer(name, 2); 957 *name = bag->bagname; 958 PetscFunctionReturn(PETSC_SUCCESS); 959 } 960 961 /*@C 962 PetscBagGetData - Gives back the user - access to memory that 963 can be used for storing user-data-structure 964 965 Not Collective 966 967 Input Parameter: 968 . bag - the bag of values 969 970 Output Parameter: 971 . 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 972 defining the bag 973 974 Level: intermediate 975 976 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()` 977 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 978 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 979 @*/ 980 PetscErrorCode PetscBagGetData(PetscBag bag, void **data) 981 { 982 PetscFunctionBegin; 983 PetscAssertPointer(bag, 1); 984 PetscAssertPointer(data, 2); 985 *data = bag->structlocation; 986 PetscFunctionReturn(PETSC_SUCCESS); 987 } 988 989 /*@ 990 PetscBagSetOptionsPrefix - Sets the prefix used for searching for all 991 `PetscBag` items in the options database. 992 993 Logically Collective 994 995 Level: intermediate 996 997 Input Parameters: 998 + bag - the bag of values 999 - pre - the prefix to prepend all Bag item names with. 1000 1001 Note: 1002 Must be called prior to registering any of the bag items. 1003 1004 .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 1005 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 1006 @*/ 1007 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[]) 1008 { 1009 PetscFunctionBegin; 1010 PetscAssertPointer(bag, 1); 1011 if (pre) { 1012 PetscAssertPointer(pre, 2); 1013 PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 1014 PetscCall(PetscFree(bag->bagprefix)); 1015 PetscCall(PetscStrallocpy(pre, &bag->bagprefix)); 1016 } else PetscCall(PetscFree(bag->bagprefix)); 1017 PetscFunctionReturn(PETSC_SUCCESS); 1018 } 1019 1020 /*@C 1021 PetscBagGetNames - Get the names of all entries in the bag 1022 1023 Not Collective 1024 1025 Input Parameter: 1026 . bag - the bag of values 1027 1028 Output Parameter: 1029 . names - array of char pointers for names 1030 1031 Level: intermediate 1032 1033 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()` 1034 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 1035 @*/ 1036 PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[]) 1037 { 1038 PetscBagItem nitem = bag->bagitems; 1039 1040 PetscFunctionBegin; 1041 PetscAssertPointer(bag, 1); 1042 PetscAssertPointer(names, 2); 1043 for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name; 1044 PetscFunctionReturn(PETSC_SUCCESS); 1045 } 1046