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 - help - longer string with more information about the value 34 35 Level: beginner 36 37 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 38 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 39 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 40 @*/ 41 PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help) 42 { 43 PetscBagItem item; 44 char nname[PETSC_BAG_NAME_LENGTH + 1]; 45 PetscBool printhelp; 46 PetscInt i = 0; 47 48 PetscFunctionBegin; 49 PetscValidPointer(bag, 1); 50 PetscValidPointer(addr, 2); 51 PetscValidPointer(list, 3); 52 PetscValidCharPointer(name, 5); 53 PetscValidCharPointer(help, 6); 54 nname[0] = '-'; 55 nname[1] = 0; 56 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 57 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 58 if (printhelp) { 59 while (list[i++]) 60 ; 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 = ((char *)addr) - ((char *)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, (char ***)&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 PetscValidPointer(bag, 1); 106 PetscValidPointer(addr, 2); 107 PetscValidCharPointer(name, 4); 108 PetscValidCharPointer(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 = ((char *)addr) - ((char *)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 PetscValidPointer(bag, 1); 157 PetscValidPointer(addr, 2); 158 PetscValidCharPointer(name, 4); 159 PetscValidCharPointer(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 = ((char *)addr) - ((char *)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 PetscValidPointer(bag, 1); 207 PetscValidPointer(addr, 2); 208 PetscValidCharPointer(name, 4); 209 PetscValidCharPointer(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 = ((char *)addr) - ((char *)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 = (PetscInt)mdefault; 252 PetscBool flg; 253 254 PetscFunctionBegin; 255 nname[0] = '-'; 256 nname[1] = 0; 257 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 258 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 259 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help)); 260 PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg)); 261 if (flg) mdefault = (PetscInt64)odefault; 262 263 PetscCall(PetscNew(&item)); 264 item->dtype = PETSC_INT; 265 item->offset = ((char *)addr) - ((char *)bag); 266 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 267 item->next = NULL; 268 item->msize = 1; 269 *(PetscInt64 *)addr = mdefault; 270 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 271 PetscFunctionReturn(PETSC_SUCCESS); 272 } 273 274 /*@C 275 PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag` 276 277 Logically Collective 278 279 Input Parameters: 280 + bag - the bag of values 281 . addr - location of boolean array in struct, for example `¶ms->b` 282 . msize - number of entries in array 283 . name - name of the boolean array 284 - help - longer string with more information about the value 285 286 Level: beginner 287 288 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 289 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 290 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 291 @*/ 292 PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help) 293 { 294 PetscBagItem item; 295 char nname[PETSC_BAG_NAME_LENGTH + 1]; 296 PetscBool printhelp; 297 PetscInt i, tmp = msize; 298 299 PetscFunctionBegin; 300 PetscValidPointer(bag, 1); 301 PetscValidPointer(addr, 2); 302 PetscValidCharPointer(name, 4); 303 PetscValidCharPointer(help, 5); 304 nname[0] = '-'; 305 nname[1] = 0; 306 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 307 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 308 if (printhelp) { 309 PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name)); 310 for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i)); 311 PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help)); 312 } 313 PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, (PetscBool *)addr, &tmp, NULL)); 314 315 PetscCall(PetscNew(&item)); 316 item->dtype = PETSC_BOOL; 317 item->offset = ((char *)addr) - ((char *)bag); 318 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 319 item->next = NULL; 320 item->msize = msize; 321 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 322 PetscFunctionReturn(PETSC_SUCCESS); 323 } 324 325 /*@C 326 PetscBagRegisterString - add a string value to a `PetscBag` 327 328 Logically Collective 329 330 Input Parameters: 331 + bag - the bag of values 332 . addr - location of start of string in struct, for example `¶ms->mystring` 333 . msize - length of the string space in the struct 334 . mdefault - the initial value 335 . name - name of the string 336 - help - longer string with more information about the value 337 338 Level: beginner 339 340 Note: 341 The struct must have the field char mystring[`msize`]; not char *mystring 342 343 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 344 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 345 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 346 @*/ 347 PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help) 348 { 349 PetscBagItem item; 350 char nname[PETSC_BAG_NAME_LENGTH + 1]; 351 PetscBool printhelp; 352 353 PetscFunctionBegin; 354 PetscValidPointer(bag, 1); 355 PetscValidPointer(addr, 2); 356 PetscValidCharPointer(mdefault, 4); 357 PetscValidCharPointer(name, 5); 358 PetscValidCharPointer(help, 6); 359 nname[0] = '-'; 360 nname[1] = 0; 361 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 362 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 363 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help)); 364 365 PetscCall(PetscNew(&item)); 366 item->dtype = PETSC_CHAR; 367 item->offset = ((char *)addr) - ((char *)bag); 368 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 369 item->next = NULL; 370 item->msize = msize; 371 if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1)); 372 PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL)); 373 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 374 PetscFunctionReturn(PETSC_SUCCESS); 375 } 376 377 /*@C 378 PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag` 379 380 Logically Collective 381 382 Input Parameters: 383 + bag - the bag of values 384 . addr - location of `PetscReal` in struct, for example `¶ms->r` 385 . mdefault - the initial value 386 . name - name of the variable 387 - help - longer string with more information about the value 388 389 Level: beginner 390 391 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 392 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 393 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 394 @*/ 395 PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help) 396 { 397 PetscBagItem item; 398 char nname[PETSC_BAG_NAME_LENGTH + 1]; 399 PetscBool printhelp; 400 401 PetscFunctionBegin; 402 PetscValidPointer(bag, 1); 403 PetscValidPointer(addr, 2); 404 PetscValidCharPointer(name, 4); 405 PetscValidCharPointer(help, 5); 406 nname[0] = '-'; 407 nname[1] = 0; 408 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 409 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 410 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help)); 411 PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL)); 412 413 PetscCall(PetscNew(&item)); 414 item->dtype = PETSC_REAL; 415 item->offset = ((char *)addr) - ((char *)bag); 416 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 417 item->next = NULL; 418 item->msize = 1; 419 *(PetscReal *)addr = mdefault; 420 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 421 PetscFunctionReturn(PETSC_SUCCESS); 422 } 423 424 /*@C 425 PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag` 426 427 Logically Collective 428 429 Input Parameters: 430 + bag - the bag of values 431 . addr - location of `PetscScalar` in struct, for example `¶ms->c` 432 . mdefault - the initial value 433 . name - name of the variable 434 - help - longer string with more information about the value 435 436 Level: beginner 437 438 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 439 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 440 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 441 @*/ 442 PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help) 443 { 444 PetscBagItem item; 445 char nname[PETSC_BAG_NAME_LENGTH + 1]; 446 PetscBool printhelp; 447 448 PetscFunctionBegin; 449 PetscValidPointer(bag, 1); 450 PetscValidPointer(addr, 2); 451 PetscValidCharPointer(name, 4); 452 PetscValidCharPointer(help, 5); 453 nname[0] = '-'; 454 nname[1] = 0; 455 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 456 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 457 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help)); 458 PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL)); 459 460 PetscCall(PetscNew(&item)); 461 item->dtype = PETSC_SCALAR; 462 item->offset = ((char *)addr) - ((char *)bag); 463 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 464 item->next = NULL; 465 item->msize = 1; 466 *(PetscScalar *)addr = mdefault; 467 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 468 PetscFunctionReturn(PETSC_SUCCESS); 469 } 470 471 /*@C 472 PetscBagRegisterBool - add a `PetscBool` to a `PetscBag` 473 474 Logically Collective 475 476 Input Parameters: 477 + bag - the bag of values 478 . addr - location of `PetscBool` in struct, for example `¶ms->b` 479 . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE` 480 . name - name of the variable 481 - help - longer string with more information about the value 482 483 Level: beginner 484 485 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 486 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 487 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 488 @*/ 489 PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help) 490 { 491 PetscBagItem item; 492 char nname[PETSC_BAG_NAME_LENGTH + 1]; 493 PetscBool printhelp; 494 495 PetscFunctionBegin; 496 PetscValidPointer(bag, 1); 497 PetscValidPointer(addr, 2); 498 PetscValidCharPointer(name, 4); 499 PetscValidCharPointer(help, 5); 500 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 501 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); 502 nname[0] = '-'; 503 nname[1] = 0; 504 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 505 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 506 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help)); 507 PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL)); 508 509 PetscCall(PetscNew(&item)); 510 item->dtype = PETSC_BOOL; 511 item->offset = ((char *)addr) - ((char *)bag); 512 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 513 item->next = NULL; 514 item->msize = 1; 515 *(PetscBool *)addr = mdefault; 516 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 517 PetscFunctionReturn(PETSC_SUCCESS); 518 } 519 520 /*@C 521 PetscBagDestroy - Destroys a `PetscBag` 522 523 Collective 524 525 Input Parameter: 526 . bag - the bag of values 527 528 Level: beginner 529 530 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 531 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 532 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 533 @*/ 534 PetscErrorCode PetscBagDestroy(PetscBag *bag) 535 { 536 PetscBagItem nitem; 537 538 PetscFunctionBegin; 539 if (!*bag) PetscFunctionReturn(PETSC_SUCCESS); 540 PetscValidPointer(*bag, 1); 541 nitem = (*bag)->bagitems; 542 while (nitem) { 543 PetscBagItem item = nitem->next; 544 545 if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list)); 546 PetscCall(PetscFree(nitem)); 547 nitem = item; 548 } 549 if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix)); 550 PetscCall(PetscFree(*bag)); 551 PetscFunctionReturn(PETSC_SUCCESS); 552 } 553 554 /*@ 555 PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database 556 557 Collective 558 559 Input Parameter: 560 . bag - the bag of values 561 562 Level: beginner 563 564 Note: 565 The options database keys for the entries are of the form `-[bagprefix]_name value` 566 567 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 568 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 569 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()` 570 @*/ 571 PetscErrorCode PetscBagSetFromOptions(PetscBag bag) 572 { 573 PetscBagItem nitem = bag->bagitems; 574 char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3]; 575 PetscInt n; 576 577 PetscFunctionBegin; 578 PetscValidPointer(bag, 1); 579 PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname))); 580 PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname))); 581 PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname))); 582 PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL); 583 while (nitem) { 584 name[0] = '-'; 585 name[1] = 0; 586 PetscCall(PetscStrlcat(name, nitem->name, sizeof(name))); 587 if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */ 588 char *value = (char *)(((char *)bag) + nitem->offset); 589 PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL)); 590 } else if (nitem->dtype == PETSC_REAL) { 591 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 592 if (nitem->msize == 1) { 593 PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL)); 594 } else { 595 n = nitem->msize; 596 PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL)); 597 } 598 } else if (nitem->dtype == PETSC_SCALAR) { 599 PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset); 600 PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL)); 601 } else if (nitem->dtype == PETSC_INT) { 602 PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset); 603 if (nitem->msize == 1) { 604 PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL)); 605 } else { 606 n = nitem->msize; 607 PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL)); 608 } 609 } else if (nitem->dtype == PETSC_ENUM) { 610 PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset); 611 PetscInt i = 0; 612 while (nitem->list[i++]) 613 ; 614 PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL)); 615 } else if (nitem->dtype == PETSC_BOOL) { 616 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 617 if (nitem->msize == 1) { 618 PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL)); 619 } else { 620 n = nitem->msize; 621 PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL)); 622 } 623 } 624 nitem = nitem->next; 625 } 626 PetscOptionsEnd(); 627 PetscFunctionReturn(PETSC_SUCCESS); 628 } 629 630 /*@C 631 PetscBagView - Views a bag of values as either ASCII text or a binary file 632 633 Collective 634 635 Input Parameters: 636 + bag - the bag of values 637 - viewer - location to view the values 638 639 Level: beginner 640 641 Note: 642 Currently PETSc bags saved in a binary file can only be read back 643 in on a machine with the same binary format. 644 645 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 646 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 647 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 648 @*/ 649 PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view) 650 { 651 PetscBool isascii, isbinary; 652 PetscBagItem nitem = bag->bagitems; 653 654 PetscFunctionBegin; 655 PetscValidPointer(bag, 1); 656 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2); 657 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 658 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 659 if (isascii) { 660 if (bag->bagprefix) { 661 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp)); 662 } else { 663 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp)); 664 } 665 while (nitem) { 666 if (nitem->dtype == PETSC_CHAR) { 667 char *value = (char *)(((char *)bag) + nitem->offset); 668 char tmp = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */ 669 value[nitem->msize - 1] = 0; 670 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help)); 671 value[nitem->msize - 1] = tmp; 672 } else if (nitem->dtype == PETSC_REAL) { 673 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 674 PetscInt i; 675 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 676 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i])); 677 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 678 } else if (nitem->dtype == PETSC_SCALAR) { 679 PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset); 680 #if defined(PETSC_USE_COMPLEX) 681 if ((double)PetscImaginaryPart(value)) { 682 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help)); 683 } else { 684 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help)); 685 } 686 #else 687 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)value, nitem->help)); 688 #endif 689 } else if (nitem->dtype == PETSC_INT) { 690 PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset); 691 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 692 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i])); 693 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 694 } else if (nitem->dtype == PETSC_BOOL) { 695 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 696 PetscInt i; 697 /* some Fortran compilers use -1 as boolean */ 698 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 699 for (i = 0; i < nitem->msize; i++) { 700 if (((int)value[i]) == -1) value[i] = PETSC_TRUE; 701 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 702 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])); 703 PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]])); 704 } 705 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 706 } else if (nitem->dtype == PETSC_ENUM) { 707 PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset); 708 PetscInt i = 0; 709 while (nitem->list[i++]) 710 ; 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 /*@C 753 PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed. 754 755 Collective 756 757 Input Parameters: 758 + obj - 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 PetscValidPointer(bag, 1); 778 if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix)); 779 prefix = bobj ? bprefix : bag->bagprefix; 780 PetscCall(PetscOptionsGetViewer(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 /*@C 793 PetscBagLoad - Loads a bag of values from a binary file 794 795 Collective 796 797 Input Parameters: 798 + viewer - 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 PetscValidPointer(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 %d then passed in bag %d", (int)bagcount, (int)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 A 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 A struct is too large 887 888 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 889 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 890 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `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 PetscValidPointer(bag, 3); 898 PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize)); 899 PetscCall(PetscCalloc(totalsize, bag)); 900 901 (*bag)->bagsize = totalsize; 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 /*@C 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 PetscValidPointer(bag, 1); 928 PetscValidCharPointer(name, 2); 929 PetscValidCharPointer(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, char **name) 953 { 954 PetscFunctionBegin; 955 PetscValidPointer(bag, 1); 956 PetscValidPointer(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 PetscValidPointer(bag, 1); 984 PetscValidPointer(data, 2); 985 *data = bag->structlocation; 986 PetscFunctionReturn(PETSC_SUCCESS); 987 } 988 989 /*@C 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 - prefix - 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 1008 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[]) 1009 { 1010 PetscFunctionBegin; 1011 PetscValidPointer(bag, 1); 1012 if (pre) { 1013 PetscValidCharPointer(pre, 2); 1014 PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 1015 PetscCall(PetscFree(bag->bagprefix)); 1016 PetscCall(PetscStrallocpy(pre, &(bag->bagprefix))); 1017 } else PetscCall(PetscFree(bag->bagprefix)); 1018 PetscFunctionReturn(PETSC_SUCCESS); 1019 } 1020 1021 /*@C 1022 PetscBagGetNames - Get the names of all entries in the bag 1023 1024 Not Collective 1025 1026 Input Parameters: 1027 + bag - the bag of values 1028 - names - array of the correct size to hold names, must be long enough to hold all the names 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