Actual source code: bag.c

  1: #include <petsc/private/petscimpl.h>
  2: #include <petsc/private/bagimpl.h>
  3: #include <petscviewer.h>

  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;

 16:     while (nitem->next) nitem = nitem->next;
 17:     nitem->next = item;
 18:   } else bag->bagitems = item;
 19:   bag->count++;
 20:   PetscFunctionReturn(PETSC_SUCCESS);
 21: }

 23: /*@C
 24:    PetscBagRegisterEnum - add an enum value to a `PetscBag`

 26:    Logically Collective

 28:    Input Parameters:
 29: +  bag - the bag of values
 30: .  addr - location of enum in struct, for example `&params->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

 35:    Level: beginner

 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;

 48:   PetscFunctionBegin;
 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));

 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: }

 79: /*@C
 80:    PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag`

 82:    Logically Collective

 84:    Input Parameters:
 85: +  bag - the bag of values
 86: .  addr - location of integer in struct, for example `&params->i`
 87: .  msize - number of entries in array
 88: .  name - name of the array
 89: -  help - longer string with more information about the value

 91:    Level: beginner

 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;

104:   PetscFunctionBegin;
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));

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: }

130: /*@C
131:    PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag`

133:    Logically Collective

135:    Input Parameters:
136: +  bag - the bag of values
137: .  addr - location of real array in struct, for example `&params->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

142:    Level: beginner

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;

155:   PetscFunctionBegin;
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));

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: }

181: /*@C
182:    PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag`

184:    Logically Collective

186:    Input Parameters:
187: +  bag - the bag of values
188: .  addr - location of integer in struct, for example `&params->i`
189: .  mdefault - the initial value
190: .  name - name of the integer
191: -  help - longer string with more information about the value

193:    Level: beginner

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;

205:   PetscFunctionBegin;
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));

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: }

228: /*@C
229:    PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`

231:    Logically Collective

233:    Input Parameters:
234: +  bag - the bag of values
235: .  addr - location of integer in struct, for example `&params->i`
236: .  mdefault - the initial value
237: .  name - name of the integer
238: -  help - longer string with more information about the value

240:    Level: beginner

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;

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;

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: }

274: /*@C
275:    PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`

277:    Logically Collective

279:    Input Parameters:
280: +  bag - the bag of values
281: .  addr - location of boolean array in struct, for example `&params->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

286:    Level: beginner

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;

299:   PetscFunctionBegin;
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));

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: }

325: /*@C
326:    PetscBagRegisterString - add a string value to a `PetscBag`

328:    Logically Collective

330:    Input Parameters:
331: +  bag - the bag of values
332: .  addr - location of start of string in struct, for example `&params->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

338:    Level: beginner

340:    Note:
341:    The struct must have the field char mystring[`msize`]; not char *mystring

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;

353:   PetscFunctionBegin;
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));

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: }

377: /*@C
378:    PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`

380:    Logically Collective

382:    Input Parameters:
383: +  bag - the bag of values
384: .  addr - location of `PetscReal` in struct, for example `&params->r`
385: .  mdefault - the initial value
386: .  name - name of the variable
387: -  help - longer string with more information about the value

389:    Level: beginner

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;

401:   PetscFunctionBegin;
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));

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: }

424: /*@C
425:    PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`

427:    Logically Collective

429:    Input Parameters:
430: +  bag - the bag of values
431: .  addr - location of `PetscScalar` in struct, for example `&params->c`
432: .  mdefault - the initial value
433: .  name - name of the variable
434: -  help - longer string with more information about the value

436:    Level: beginner

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;

448:   PetscFunctionBegin;
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));

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: }

471: /*@C
472:    PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`

474:    Logically Collective

476:    Input Parameters:
477: +  bag - the bag of values
478: .  addr - location of `PetscBool` in struct, for example `&params->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

483:    Level: beginner

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;

495:   PetscFunctionBegin;
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));

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: }

520: /*@C
521:    PetscBagDestroy - Destroys a `PetscBag`

523:    Collective

525:    Input Parameter:
526: .  bag - the bag of values

528:    Level: beginner

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;

538:   PetscFunctionBegin;
539:   if (!*bag) PetscFunctionReturn(PETSC_SUCCESS);
541:   nitem = (*bag)->bagitems;
542:   while (nitem) {
543:     PetscBagItem item = nitem->next;

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: }

554: /*@
555:    PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database

557:    Collective

559:    Input Parameter:
560: .  bag - the bag of values

562:    Level: beginner

564:    Note:
565:    The options database keys for the entries are of the form `-[bagprefix]_name value`

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;

577:   PetscFunctionBegin;
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: }

630: /*@C
631:    PetscBagView - Views a bag of values as either ASCII text or a binary file

633:    Collective

635:    Input Parameters:
636: +  bag - the bag of values
637: -  viewer - location to view the values

639:    Level: beginner

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.

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;

654:   PetscFunctionBegin;
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;

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: }

752: /*@C
753:   PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed.

755:   Collective

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

762:   Level: intermediate

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;

774:   PetscFunctionBegin;
775:   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
776:   incall = PETSC_TRUE;
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: }

792: /*@C
793:    PetscBagLoad - Loads a bag of values from a binary file

795:    Collective

797:    Input Parameters:
798: +  viewer - file to load values from
799: -  bag - the bag of values

801:    Level: beginner

803:    Note:
804:     You must have created and registered all the fields in the bag before loading into it. This only loads values.

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;

819:   PetscFunctionBegin;
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");

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));

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));

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: }

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

870:   Collective

872:   Input Parameters:
873: +  comm - communicator to share bag
874: -  bagsize - size of the C structure holding the values, for example sizeof(mystruct)

876:   Output Parameter:
877: .   bag - the bag of values

879:   Level: Intermediate

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

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

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);

896:   PetscFunctionBegin;
898:   PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize));
899:   PetscCall(PetscCalloc(totalsize, bag));

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: }

908: /*@C
909:     PetscBagSetName - Sets the name of a bag of values

911:   Not Collective

913:   Level: Intermediate

915:   Input Parameters:
916: +   bag - the bag of values
917: .   name - the name assigned to the bag
918: -   help - help message for bag

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;
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: }

935: /*@C
936:     PetscBagGetName - Gets the name of a bag of values

938:   Not Collective

940:   Level: Intermediate

942:   Input Parameter:
943: .   bag - the bag of values

945:   Output Parameter:
946: .   name - the name assigned to the bag

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;
957:   *name = bag->bagname;
958:   PetscFunctionReturn(PETSC_SUCCESS);
959: }

961: /*@C
962:     PetscBagGetData - Gives back the user - access to memory that
963:     can be used for storing user-data-structure

965:   Not Collective

967:   Input Parameter:
968: .   bag - the bag of values

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

974:   Level: Intermediate

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;
985:   *data = bag->structlocation;
986:   PetscFunctionReturn(PETSC_SUCCESS);
987: }

989: /*@C
990:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
991:   `PetscBag` items in the options database.

993:   Logically Collective

995:   Level: Intermediate

997:   Input Parameters:
998: +   bag - the bag of values
999: -   prefix - the prefix to prepend all Bag item names with.

1001:   Note:
1002:   Must be called prior to registering any of the bag items.

1004: .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
1005:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
1006: @*/

1008: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1009: {
1010:   PetscFunctionBegin;
1012:   if (pre) {
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: }

1021: /*@C
1022:   PetscBagGetNames - Get the names of all entries in the bag

1024:   Not Collective

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

1030:   Output Parameter:
1031: . names - array of char pointers for names

1033:   Level: intermediate

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;

1042:   PetscFunctionBegin;
1045:   for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
1046:   PetscFunctionReturn(PETSC_SUCCESS);
1047: }