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