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(0); 21 } 22 23 /*@C 24 PetscBagRegisterEnum - add an enum value to a `PetscBag` 25 26 Logically Collective on bag 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(0); 77 } 78 79 /*@C 80 PetscBagRegisterIntArray - add an `PetscInt` array to a `PetscBag` 81 82 Logically Collective on bag 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(0); 128 } 129 130 /*@C 131 PetscBagRegisterRealArray - add an `PetscReal` array to a `PetscBag` 132 133 Logically Collective on bag 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(0); 179 } 180 181 /*@C 182 PetscBagRegisterInt - add an `PetscInt` value to a `PetscBag` 183 184 Logically Collective on bag 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(0); 226 } 227 228 /*@C 229 PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag` 230 231 Logically Collective on bag 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(0); 272 } 273 274 /*@C 275 PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag` 276 277 Logically Collective on bag 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(0); 323 } 324 325 /*@C 326 PetscBagRegisterString - add a string value to a `PetscBag` 327 328 Logically Collective on bag 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: The struct should have the field char mystring[msize]; not char *mystring 341 342 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 343 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 344 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 345 @*/ 346 PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help) 347 { 348 PetscBagItem item; 349 char nname[PETSC_BAG_NAME_LENGTH + 1]; 350 PetscBool printhelp; 351 352 PetscFunctionBegin; 353 PetscValidPointer(bag, 1); 354 PetscValidPointer(addr, 2); 355 PetscValidCharPointer(mdefault, 4); 356 PetscValidCharPointer(name, 5); 357 PetscValidCharPointer(help, 6); 358 nname[0] = '-'; 359 nname[1] = 0; 360 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 361 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 362 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help)); 363 364 PetscCall(PetscNew(&item)); 365 item->dtype = PETSC_CHAR; 366 item->offset = ((char *)addr) - ((char *)bag); 367 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 368 item->next = NULL; 369 item->msize = msize; 370 if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1)); 371 PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL)); 372 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 373 PetscFunctionReturn(0); 374 } 375 376 /*@C 377 PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag` 378 379 Logically Collective on bag 380 381 Input Parameters: 382 + bag - the bag of values 383 . addr - location of double in struct, for example `¶ms->r` 384 . mdefault - the initial value 385 . name - name of the variable 386 - help - longer string with more information about the value 387 388 Level: beginner 389 390 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 391 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 392 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 393 @*/ 394 PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help) 395 { 396 PetscBagItem item; 397 char nname[PETSC_BAG_NAME_LENGTH + 1]; 398 PetscBool printhelp; 399 400 PetscFunctionBegin; 401 PetscValidPointer(bag, 1); 402 PetscValidPointer(addr, 2); 403 PetscValidCharPointer(name, 4); 404 PetscValidCharPointer(help, 5); 405 nname[0] = '-'; 406 nname[1] = 0; 407 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 408 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 409 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help)); 410 PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL)); 411 412 PetscCall(PetscNew(&item)); 413 item->dtype = PETSC_REAL; 414 item->offset = ((char *)addr) - ((char *)bag); 415 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 416 item->next = NULL; 417 item->msize = 1; 418 *(PetscReal *)addr = mdefault; 419 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 420 PetscFunctionReturn(0); 421 } 422 423 /*@C 424 PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag` 425 426 Logically Collective on bag 427 428 Input Parameters: 429 + bag - the bag of values 430 . addr - location of scalar in struct, for example `¶ms->c` 431 . mdefault - the initial value 432 . name - name of the variable 433 - help - longer string with more information about the value 434 435 Level: beginner 436 437 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 438 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 439 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 440 @*/ 441 PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help) 442 { 443 PetscBagItem item; 444 char nname[PETSC_BAG_NAME_LENGTH + 1]; 445 PetscBool printhelp; 446 447 PetscFunctionBegin; 448 PetscValidPointer(bag, 1); 449 PetscValidPointer(addr, 2); 450 PetscValidCharPointer(name, 4); 451 PetscValidCharPointer(help, 5); 452 nname[0] = '-'; 453 nname[1] = 0; 454 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 455 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 456 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help)); 457 PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL)); 458 459 PetscCall(PetscNew(&item)); 460 item->dtype = PETSC_SCALAR; 461 item->offset = ((char *)addr) - ((char *)bag); 462 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 463 item->next = NULL; 464 item->msize = 1; 465 *(PetscScalar *)addr = mdefault; 466 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 467 PetscFunctionReturn(0); 468 } 469 470 /*@C 471 PetscBagRegisterBool - add a `PetscBool` to a `PetscBag` 472 473 Logically Collective on bag 474 475 Input Parameters: 476 + bag - the bag of values 477 . addr - location of logical in struct, for example `¶ms->b` 478 . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE` 479 . name - name of the variable 480 - help - longer string with more information about the value 481 482 Level: beginner 483 484 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 485 `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 486 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 487 @*/ 488 PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help) 489 { 490 PetscBagItem item; 491 char nname[PETSC_BAG_NAME_LENGTH + 1]; 492 PetscBool printhelp; 493 494 PetscFunctionBegin; 495 PetscValidPointer(bag, 1); 496 PetscValidPointer(addr, 2); 497 PetscValidCharPointer(name, 4); 498 PetscValidCharPointer(help, 5); 499 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 500 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); 501 nname[0] = '-'; 502 nname[1] = 0; 503 PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH)); 504 PetscCall(PetscOptionsHasHelp(NULL, &printhelp)); 505 if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help)); 506 PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL)); 507 508 PetscCall(PetscNew(&item)); 509 item->dtype = PETSC_BOOL; 510 item->offset = ((char *)addr) - ((char *)bag); 511 PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help); 512 item->next = NULL; 513 item->msize = 1; 514 *(PetscBool *)addr = mdefault; 515 PetscCall(PetscBagRegister_Private(bag, item, name, help)); 516 PetscFunctionReturn(0); 517 } 518 519 /*@C 520 PetscBagDestroy - Destroys a `PetscBag` 521 522 Collective on bag 523 524 Input Parameter: 525 . bag - the bag of values 526 527 Level: beginner 528 529 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 530 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 531 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 532 @*/ 533 PetscErrorCode PetscBagDestroy(PetscBag *bag) 534 { 535 PetscBagItem nitem; 536 537 PetscFunctionBegin; 538 if (!*bag) PetscFunctionReturn(0); 539 PetscValidPointer(*bag, 1); 540 nitem = (*bag)->bagitems; 541 while (nitem) { 542 PetscBagItem item = nitem->next; 543 544 if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list)); 545 PetscCall(PetscFree(nitem)); 546 nitem = item; 547 } 548 if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix)); 549 PetscCall(PetscFree(*bag)); 550 PetscFunctionReturn(0); 551 } 552 553 /*@ 554 PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database 555 556 Collective on bag 557 558 Input Parameter: 559 . bag - the bag of values 560 561 Level: beginner 562 563 Note: 564 The options database keys for the entries are of the form `-[bagprefix]_name value` 565 566 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 567 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 568 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()` 569 @*/ 570 PetscErrorCode PetscBagSetFromOptions(PetscBag bag) 571 { 572 PetscBagItem nitem = bag->bagitems; 573 char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3]; 574 PetscInt n; 575 576 PetscFunctionBegin; 577 PetscValidPointer(bag, 1); 578 PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname))); 579 PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname))); 580 PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname))); 581 PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL); 582 while (nitem) { 583 name[0] = '-'; 584 name[1] = 0; 585 PetscCall(PetscStrlcat(name, nitem->name, sizeof(name))); 586 if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */ 587 char *value = (char *)(((char *)bag) + nitem->offset); 588 PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL)); 589 } else if (nitem->dtype == PETSC_REAL) { 590 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 591 if (nitem->msize == 1) { 592 PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL)); 593 } else { 594 n = nitem->msize; 595 PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL)); 596 } 597 } else if (nitem->dtype == PETSC_SCALAR) { 598 PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset); 599 PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL)); 600 } else if (nitem->dtype == PETSC_INT) { 601 PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset); 602 if (nitem->msize == 1) { 603 PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL)); 604 } else { 605 n = nitem->msize; 606 PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL)); 607 } 608 } else if (nitem->dtype == PETSC_ENUM) { 609 PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset); 610 PetscInt i = 0; 611 while (nitem->list[i++]) 612 ; 613 PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL)); 614 } else if (nitem->dtype == PETSC_BOOL) { 615 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 616 if (nitem->msize == 1) { 617 PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL)); 618 } else { 619 n = nitem->msize; 620 PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL)); 621 } 622 } 623 nitem = nitem->next; 624 } 625 PetscOptionsEnd(); 626 PetscFunctionReturn(0); 627 } 628 629 /*@C 630 PetscBagView - Views a bag of values as either ASCII text or a binary file 631 632 Collective on bag 633 634 Input Parameters: 635 + bag - the bag of values 636 - viewer - location to view the values 637 638 Level: beginner 639 640 Note: 641 Currently PETSc bags saved in a binary file can only be read back 642 in on a machine of the same architecture. 643 644 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()` 645 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 646 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()` 647 @*/ 648 PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view) 649 { 650 PetscBool isascii, isbinary; 651 PetscBagItem nitem = bag->bagitems; 652 653 PetscFunctionBegin; 654 PetscValidPointer(bag, 1); 655 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2); 656 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii)); 657 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 658 if (isascii) { 659 if (bag->bagprefix) { 660 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp)); 661 } else { 662 PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp)); 663 } 664 while (nitem) { 665 if (nitem->dtype == PETSC_CHAR) { 666 char *value = (char *)(((char *)bag) + nitem->offset); 667 char tmp = value[nitem->msize - 1]; /* special handling for fortran chars wihout null terminator */ 668 value[nitem->msize - 1] = 0; 669 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help)); 670 value[nitem->msize - 1] = tmp; 671 } else if (nitem->dtype == PETSC_REAL) { 672 PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset); 673 PetscInt i; 674 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 675 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i])); 676 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 677 } else if (nitem->dtype == PETSC_SCALAR) { 678 PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset); 679 #if defined(PETSC_USE_COMPLEX) 680 if ((double)PetscImaginaryPart(value)) { 681 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help)); 682 } else { 683 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help)); 684 } 685 #else 686 PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)value, nitem->help)); 687 #endif 688 } else if (nitem->dtype == PETSC_INT) { 689 PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset); 690 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 691 for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i])); 692 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 693 } else if (nitem->dtype == PETSC_BOOL) { 694 PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset); 695 PetscInt i; 696 /* some Fortran compilers use -1 as boolean */ 697 PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name)); 698 for (i = 0; i < nitem->msize; i++) { 699 if (((int)value[i]) == -1) value[i] = PETSC_TRUE; 700 /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */ 701 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])); 702 PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]])); 703 } 704 PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help)); 705 } else if (nitem->dtype == PETSC_ENUM) { 706 PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset); 707 PetscInt i = 0; 708 while (nitem->list[i++]) 709 ; 710 PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help)); 711 } 712 nitem = nitem->next; 713 } 714 } else if (isbinary) { 715 PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype; 716 PetscInt deprecatedbagsize = 0; 717 PetscViewerFormat format; 718 PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT)); 719 PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT)); 720 PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT)); 721 PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 722 PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 723 while (nitem) { 724 PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT)); 725 dtype = (PetscInt)nitem->dtype; 726 PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT)); 727 PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR)); 728 PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR)); 729 PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT)); 730 /* some Fortran compilers use -1 as boolean */ 731 if (dtype == PETSC_BOOL && ((*(int *)(((char *)bag) + nitem->offset) == -1))) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE; 732 733 PetscCall(PetscViewerBinaryWrite(view, (((char *)bag) + nitem->offset), nitem->msize, nitem->dtype)); 734 if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list)); 735 nitem = nitem->next; 736 } 737 PetscCall(PetscViewerGetFormat(view, &format)); 738 if (format == PETSC_VIEWER_BINARY_MATLAB) { 739 MPI_Comm comm; 740 FILE *info; 741 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 742 PetscCall(PetscViewerBinaryGetInfoPointer(view, &info)); 743 PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n")); 744 PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname)); 745 PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n")); 746 } 747 } 748 PetscFunctionReturn(0); 749 } 750 751 /*@C 752 PetscBagViewFromOptions - Processes command line options to determine if/how a PetscBag is to be viewed. 753 754 Collective on bag 755 756 Input Parameters: 757 + obj - the object 758 . bobj - optional other object that provides prefix (if NULL then the prefix in obj is used) 759 - optionname - option to activate viewing 760 761 Level: intermediate 762 763 .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer` 764 @*/ 765 PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[]) 766 { 767 static PetscBool incall = PETSC_FALSE; 768 PetscViewer viewer; 769 PetscViewerFormat format; 770 const char *prefix, *bprefix = NULL; 771 PetscBool flg; 772 773 PetscFunctionBegin; 774 if (incall) PetscFunctionReturn(0); 775 incall = PETSC_TRUE; 776 PetscValidPointer(bag, 1); 777 if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix)); 778 prefix = bobj ? bprefix : bag->bagprefix; 779 PetscCall(PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg)); 780 if (flg) { 781 PetscCall(PetscViewerPushFormat(viewer, format)); 782 PetscCall(PetscBagView(bag, viewer)); 783 PetscCall(PetscViewerFlush(viewer)); 784 PetscCall(PetscViewerPopFormat(viewer)); 785 PetscCall(PetscViewerDestroy(&viewer)); 786 } 787 incall = PETSC_FALSE; 788 PetscFunctionReturn(0); 789 } 790 791 /*@C 792 PetscBagLoad - Loads a bag of values from a binary file 793 794 Collective on view 795 796 Input Parameters: 797 + viewer - file to load values from 798 - bag - the bag of values 799 800 Note: 801 You must have created and registered all the fields in the bag before loading into it. 802 803 Level: beginner 804 805 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()` 806 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 807 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()` 808 @*/ 809 PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag) 810 { 811 PetscBool isbinary; 812 PetscInt classid, bagcount, dtype, msize, offset, deprecatedbagsize; 813 char name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list; 814 PetscBagItem nitem; 815 MPI_Comm comm; 816 PetscMPIInt flag; 817 818 PetscFunctionBegin; 819 PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1); 820 PetscValidPointer(bag, 2); 821 PetscCall(PetscObjectGetComm((PetscObject)view, &comm)); 822 PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag)); 823 PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag"); 824 PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary)); 825 PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type"); 826 827 PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT)); 828 PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file"); 829 PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT)); 830 PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT)); 831 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); 832 PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 833 PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 834 835 nitem = bag->bagitems; 836 for (PetscInt i = 0; i < bagcount; i++) { 837 PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT)); 838 /* ignore the offset in the file */ 839 PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT)); 840 PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR)); 841 PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR)); 842 PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT)); 843 844 if (dtype == (PetscInt)PETSC_CHAR) { 845 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR)); 846 } else if (dtype == (PetscInt)PETSC_REAL) { 847 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL)); 848 } else if (dtype == (PetscInt)PETSC_SCALAR) { 849 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR)); 850 } else if (dtype == (PetscInt)PETSC_INT) { 851 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT)); 852 } else if (dtype == (PetscInt)PETSC_BOOL) { 853 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL)); 854 } else if (dtype == (PetscInt)PETSC_ENUM) { 855 PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM)); 856 PetscCall(PetscViewerBinaryReadStringArray(view, &list)); 857 /* don't need to save list because it is already registered in the bag */ 858 PetscCall(PetscFree(list)); 859 } 860 nitem = nitem->next; 861 } 862 PetscFunctionReturn(0); 863 } 864 865 /*@C 866 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 867 options database 868 869 Collective 870 871 Level: Intermediate 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 Notes: 881 After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout 882 883 The size of the A struct must be small enough to fit in a `PetscInt`; by default 884 `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length. 885 The warning about casting to a shorter length can be ignored below unless your A struct is too large 886 887 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 888 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 889 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 890 @*/ 891 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag) 892 { 893 const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar); 894 895 PetscFunctionBegin; 896 PetscValidPointer(bag, 3); 897 PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize)); 898 PetscCall(PetscCalloc(totalsize, bag)); 899 900 (*bag)->bagsize = totalsize; 901 (*bag)->bagcomm = comm; 902 (*bag)->bagprefix = NULL; 903 (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar)); 904 PetscFunctionReturn(0); 905 } 906 907 /*@C 908 PetscBagSetName - Sets the name of a bag of values 909 910 Not Collective 911 912 Level: Intermediate 913 914 Input Parameters: 915 + bag - the bag of values 916 . name - the name assigned to the bag 917 - help - help message for bag 918 919 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 920 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 921 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 922 @*/ 923 PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help) 924 { 925 PetscFunctionBegin; 926 PetscValidPointer(bag, 1); 927 PetscValidCharPointer(name, 2); 928 PetscValidCharPointer(help, 3); 929 PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1)); 930 PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1)); 931 PetscFunctionReturn(0); 932 } 933 934 /*@C 935 PetscBagGetName - Gets the name of a bag of values 936 937 Not Collective 938 939 Level: Intermediate 940 941 Input Parameter: 942 . bag - the bag of values 943 944 Output Parameter: 945 . name - the name assigned to the bag 946 947 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()` 948 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 949 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 950 @*/ 951 PetscErrorCode PetscBagGetName(PetscBag bag, char **name) 952 { 953 PetscFunctionBegin; 954 PetscValidPointer(bag, 1); 955 PetscValidPointer(name, 2); 956 *name = bag->bagname; 957 PetscFunctionReturn(0); 958 } 959 960 /*@C 961 PetscBagGetData - Gives back the user - access to memory that 962 can be used for storing user-data-structure 963 964 Not Collective 965 966 Level: Intermediate 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 defining the bag 973 974 .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()` 975 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 976 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 977 @*/ 978 PetscErrorCode PetscBagGetData(PetscBag bag, void **data) 979 { 980 PetscFunctionBegin; 981 PetscValidPointer(bag, 1); 982 PetscValidPointer(data, 2); 983 *data = bag->structlocation; 984 PetscFunctionReturn(0); 985 } 986 987 /*@C 988 PetscBagSetOptionsPrefix - Sets the prefix used for searching for all 989 `PetscBag` items in the options database. 990 991 Logically collective on bag 992 993 Level: Intermediate 994 995 Input Parameters: 996 + bag - the bag of values 997 - prefix - the prefix to prepend all Bag item names with. 998 999 NOTES: Must be called prior to registering any of the bag items. 1000 1001 .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()` 1002 `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()` 1003 @*/ 1004 1005 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[]) 1006 { 1007 PetscFunctionBegin; 1008 PetscValidPointer(bag, 1); 1009 if (pre) { 1010 PetscValidCharPointer(pre, 2); 1011 PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen"); 1012 PetscCall(PetscFree(bag->bagprefix)); 1013 PetscCall(PetscStrallocpy(pre, &(bag->bagprefix))); 1014 } else PetscCall(PetscFree(bag->bagprefix)); 1015 PetscFunctionReturn(0); 1016 } 1017 1018 /*@C 1019 PetscBagGetNames - Get the names of all entries in the bag 1020 1021 Not collective 1022 1023 Input Parameters: 1024 + bag - the bag of values 1025 - names - array of the correct size to hold names, must be long enough to hold all the names 1026 1027 Output Parameter: 1028 . names - array of char pointers for names 1029 1030 Level: intermediate 1031 1032 .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()` 1033 `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()` 1034 @*/ 1035 PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[]) 1036 { 1037 PetscBagItem nitem = bag->bagitems; 1038 1039 PetscFunctionBegin; 1040 PetscValidPointer(bag, 1); 1041 PetscValidPointer(names, 2); 1042 for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name; 1043 PetscFunctionReturn(0); 1044 } 1045