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