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:   PetscStrncpy(item->name, name, PETSC_BAG_NAME_LENGTH - 1);
 11:   PetscStrncpy(item->help, help, PETSC_BAG_HELP_LENGTH - 1);
 12:   if (bag->bagitems) {
 13:     PetscBagItem nitem = bag->bagitems;

 15:     while (nitem->next) nitem = nitem->next;
 16:     nitem->next = item;
 17:   } else bag->bagitems = item;
 18:   bag->count++;
 19:   return 0;
 20: }

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

 25:    Logically Collective

 27:    Input Parameters:
 28: +  bag - the bag of values
 29: .  addr - location of enum in struct, for example `&params->dt`
 30: .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
 31: .  mdefault - the initial value, cast with (`PetscEnum`)
 32: -  help - longer string with more information about the value

 34:    Level: beginner

 36: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
 37:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
 38:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
 39: @*/
 40: PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help)
 41: {
 42:   PetscBagItem item;
 43:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
 44:   PetscBool    printhelp;
 45:   PetscInt     i = 0;

 52:   nname[0] = '-';
 53:   nname[1] = 0;
 54:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
 55:   PetscOptionsHasHelp(NULL, &printhelp);
 56:   if (printhelp) {
 57:     while (list[i++])
 58:       ;
 59:     (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help);
 60:     for (i = 0; list[i + 2]; i++) (*PetscHelpPrintf)(bag->bagcomm, " %s", list[i]);
 61:     (*PetscHelpPrintf)(bag->bagcomm, "\n");
 62:   }
 63:   PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL);

 65:   PetscNew(&item);
 66:   item->dtype  = PETSC_ENUM;
 67:   item->offset = ((char *)addr) - ((char *)bag);
 69:   item->next  = NULL;
 70:   item->msize = 1;
 71:   PetscStrArrayallocpy(list, (char ***)&item->list);
 72:   *(PetscEnum *)addr = mdefault;
 73:   PetscBagRegister_Private(bag, item, name, help);
 74:   return 0;
 75: }

 77: /*@C
 78:    PetscBagRegisterIntArray - add an `PetscInt` array to a `PetscBag`

 80:    Logically Collective

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

 89:    Level: beginner

 91: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
 92:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
 93:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
 94: @*/
 95: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
 96: {
 97:   PetscBagItem item;
 98:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
 99:   PetscBool    printhelp;
100:   PetscInt     i, tmp = msize;

106:   nname[0] = '-';
107:   nname[1] = 0;
108:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
109:   PetscOptionsHasHelp(NULL, &printhelp);
110:   if (printhelp) {
111:     (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name);
112:     for (i = 0; i < msize; i++) (*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i);
113:     (*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help);
114:   }
115:   PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, (PetscInt *)addr, &tmp, NULL);

117:   PetscNew(&item);
118:   item->dtype  = PETSC_INT;
119:   item->offset = ((char *)addr) - ((char *)bag);
121:   item->next  = NULL;
122:   item->msize = msize;
123:   PetscBagRegister_Private(bag, item, name, help);
124:   return 0;
125: }

127: /*@C
128:    PetscBagRegisterRealArray - add an `PetscReal` array to a `PetscBag`

130:    Logically Collective

132:    Input Parameters:
133: +  bag - the bag of values
134: .  addr - location of real array in struct, for example `&params->d`
135: .  msize - number of entries in the array
136: .  name - name of the array
137: -  help - longer string with more information about the value

139:    Level: beginner

141: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
142:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
143:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
144: @*/
145: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
146: {
147:   PetscBagItem item;
148:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
149:   PetscBool    printhelp;
150:   PetscInt     i, tmp = msize;

156:   nname[0] = '-';
157:   nname[1] = 0;
158:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
159:   PetscOptionsHasHelp(NULL, &printhelp);
160:   if (printhelp) {
161:     (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name);
162:     for (i = 0; i < msize; i++) (*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)*((PetscReal *)addr) + i);
163:     (*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help);
164:   }
165:   PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, (PetscReal *)addr, &tmp, NULL);

167:   PetscNew(&item);
168:   item->dtype  = PETSC_REAL;
169:   item->offset = ((char *)addr) - ((char *)bag);
171:   item->next  = NULL;
172:   item->msize = msize;
173:   PetscBagRegister_Private(bag, item, name, help);
174:   return 0;
175: }

177: /*@C
178:    PetscBagRegisterInt - add an `PetscInt` value to a `PetscBag`

180:    Logically Collective

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

189:    Level: beginner

191: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
192:           `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
193:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
194: @*/
195: PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help)
196: {
197:   PetscBagItem item;
198:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
199:   PetscBool    printhelp;

205:   nname[0] = '-';
206:   nname[1] = 0;
207:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
208:   PetscOptionsHasHelp(NULL, &printhelp);
209:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help);
210:   PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL);

212:   PetscNew(&item);
213:   item->dtype  = PETSC_INT;
214:   item->offset = ((char *)addr) - ((char *)bag);
216:   item->next        = NULL;
217:   item->msize       = 1;
218:   *(PetscInt *)addr = mdefault;
219:   PetscBagRegister_Private(bag, item, name, help);
220:   return 0;
221: }

223: /*@C
224:    PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`

226:    Logically Collective

228:    Input Parameters:
229: +  bag - the bag of values
230: .  addr - location of integer in struct, for example `&params->i`
231: .  mdefault - the initial value
232: .  name - name of the integer
233: -  help - longer string with more information about the value

235:    Level: beginner

237: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
238:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
239:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
240: @*/
241: PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help)
242: {
243:   PetscBagItem item;
244:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
245:   PetscBool    printhelp;
246:   PetscInt     odefault = (PetscInt)mdefault;
247:   PetscBool    flg;

249:   nname[0] = '-';
250:   nname[1] = 0;
251:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
252:   PetscOptionsHasHelp(NULL, &printhelp);
253:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help);
254:   PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg);
255:   if (flg) mdefault = (PetscInt64)odefault;

257:   PetscNew(&item);
258:   item->dtype  = PETSC_INT;
259:   item->offset = ((char *)addr) - ((char *)bag);
261:   item->next          = NULL;
262:   item->msize         = 1;
263:   *(PetscInt64 *)addr = mdefault;
264:   PetscBagRegister_Private(bag, item, name, help);
265:   return 0;
266: }

268: /*@C
269:    PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`

271:    Logically Collective

273:    Input Parameters:
274: +  bag - the bag of values
275: .  addr - location of boolean array in struct, for example `&params->b`
276: .  msize - number of entries in array
277: .  name - name of the boolean array
278: -  help - longer string with more information about the value

280:    Level: beginner

282: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
283:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
284:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
285: @*/
286: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
287: {
288:   PetscBagItem item;
289:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
290:   PetscBool    printhelp;
291:   PetscInt     i, tmp = msize;

297:   nname[0] = '-';
298:   nname[1] = 0;
299:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
300:   PetscOptionsHasHelp(NULL, &printhelp);
301:   if (printhelp) {
302:     (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name);
303:     for (i = 0; i < msize; i++) (*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i);
304:     (*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help);
305:   }
306:   PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, (PetscBool *)addr, &tmp, NULL);

308:   PetscNew(&item);
309:   item->dtype  = PETSC_BOOL;
310:   item->offset = ((char *)addr) - ((char *)bag);
312:   item->next  = NULL;
313:   item->msize = msize;
314:   PetscBagRegister_Private(bag, item, name, help);
315:   return 0;
316: }

318: /*@C
319:    PetscBagRegisterString - add a string value to a `PetscBag`

321:    Logically Collective

323:    Input Parameters:
324: +  bag - the bag of values
325: .  addr - location of start of string in struct, for example `&params->mystring`
326: .  msize - length of the string space in the struct
327: .  mdefault - the initial value
328: .  name - name of the string
329: -  help - longer string with more information about the value

331:    Level: beginner

333:    Note: The struct should have the field char mystring[msize]; not char *mystring

335: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
336:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
337:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
338: @*/
339: PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help)
340: {
341:   PetscBagItem item;
342:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
343:   PetscBool    printhelp;

350:   nname[0] = '-';
351:   nname[1] = 0;
352:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
353:   PetscOptionsHasHelp(NULL, &printhelp);
354:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help);

356:   PetscNew(&item);
357:   item->dtype  = PETSC_CHAR;
358:   item->offset = ((char *)addr) - ((char *)bag);
360:   item->next  = NULL;
361:   item->msize = msize;
362:   if (mdefault != (char *)addr) PetscStrncpy((char *)addr, mdefault, msize - 1);
363:   PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL);
364:   PetscBagRegister_Private(bag, item, name, help);
365:   return 0;
366: }

368: /*@C
369:    PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`

371:    Logically Collective

373:    Input Parameters:
374: +  bag - the bag of values
375: .  addr - location of double in struct, for example `&params->r`
376: .  mdefault - the initial value
377: .  name - name of the variable
378: -  help - longer string with more information about the value

380:    Level: beginner

382: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
383:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
384:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
385: @*/
386: PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help)
387: {
388:   PetscBagItem item;
389:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
390:   PetscBool    printhelp;

396:   nname[0] = '-';
397:   nname[1] = 0;
398:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
399:   PetscOptionsHasHelp(NULL, &printhelp);
400:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help);
401:   PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL);

403:   PetscNew(&item);
404:   item->dtype  = PETSC_REAL;
405:   item->offset = ((char *)addr) - ((char *)bag);
407:   item->next         = NULL;
408:   item->msize        = 1;
409:   *(PetscReal *)addr = mdefault;
410:   PetscBagRegister_Private(bag, item, name, help);
411:   return 0;
412: }

414: /*@C
415:    PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`

417:    Logically Collective

419:    Input Parameters:
420: +  bag - the bag of values
421: .  addr - location of scalar in struct, for example `&params->c`
422: .  mdefault - the initial value
423: .  name - name of the variable
424: -  help - longer string with more information about the value

426:    Level: beginner

428: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
429:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
430:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
431: @*/
432: PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help)
433: {
434:   PetscBagItem item;
435:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
436:   PetscBool    printhelp;

442:   nname[0] = '-';
443:   nname[1] = 0;
444:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
445:   PetscOptionsHasHelp(NULL, &printhelp);
446:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help);
447:   PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL);

449:   PetscNew(&item);
450:   item->dtype  = PETSC_SCALAR;
451:   item->offset = ((char *)addr) - ((char *)bag);
453:   item->next           = NULL;
454:   item->msize          = 1;
455:   *(PetscScalar *)addr = mdefault;
456:   PetscBagRegister_Private(bag, item, name, help);
457:   return 0;
458: }

460: /*@C
461:    PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`

463:    Logically Collective

465:    Input Parameters:
466: +  bag - the bag of values
467: .  addr - location of logical in struct, for example `&params->b`
468: .  mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
469: .  name - name of the variable
470: -  help - longer string with more information about the value

472:    Level: beginner

474: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
475:           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
476:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
477: @*/
478: PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help)
479: {
480:   PetscBagItem item;
481:   char         nname[PETSC_BAG_NAME_LENGTH + 1];
482:   PetscBool    printhelp;

488:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
490:   nname[0] = '-';
491:   nname[1] = 0;
492:   PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH);
493:   PetscOptionsHasHelp(NULL, &printhelp);
494:   if (printhelp) (*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help);
495:   PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL);

497:   PetscNew(&item);
498:   item->dtype  = PETSC_BOOL;
499:   item->offset = ((char *)addr) - ((char *)bag);
501:   item->next         = NULL;
502:   item->msize        = 1;
503:   *(PetscBool *)addr = mdefault;
504:   PetscBagRegister_Private(bag, item, name, help);
505:   return 0;
506: }

508: /*@C
509:    PetscBagDestroy - Destroys a `PetscBag`

511:    Collective

513:    Input Parameter:
514: .  bag - the bag of values

516:    Level: beginner

518: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
519:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
520:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
521: @*/
522: PetscErrorCode PetscBagDestroy(PetscBag *bag)
523: {
524:   PetscBagItem nitem;

526:   if (!*bag) return 0;
528:   nitem = (*bag)->bagitems;
529:   while (nitem) {
530:     PetscBagItem item = nitem->next;

532:     if (nitem->list) PetscStrArrayDestroy(&nitem->list);
533:     PetscFree(nitem);
534:     nitem = item;
535:   }
536:   if ((*bag)->bagprefix) PetscFree((*bag)->bagprefix);
537:   PetscFree(*bag);
538:   return 0;
539: }

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

544:    Collective

546:    Input Parameter:
547: .  bag - the bag of values

549:    Level: beginner

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

554: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
555:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
556:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()`
557: @*/
558: PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
559: {
560:   PetscBagItem nitem = bag->bagitems;
561:   char         name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3];
562:   PetscInt     n;

565:   PetscStrncpy(helpname, bag->bagname, sizeof(helpname));
566:   PetscStrlcat(helpname, " ", sizeof(helpname));
567:   PetscStrlcat(helpname, bag->baghelp, sizeof(helpname));
568:   PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL);
569:   while (nitem) {
570:     name[0] = '-';
571:     name[1] = 0;
572:     PetscStrlcat(name, nitem->name, sizeof(name));
573:     if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
574:       char *value = (char *)(((char *)bag) + nitem->offset);
575:       PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL);
576:     } else if (nitem->dtype == PETSC_REAL) {
577:       PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
578:       if (nitem->msize == 1) {
579:         PetscOptionsReal(name, nitem->help, "", *value, value, NULL);
580:       } else {
581:         n = nitem->msize;
582:         PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL);
583:       }
584:     } else if (nitem->dtype == PETSC_SCALAR) {
585:       PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset);
586:       PetscOptionsScalar(name, nitem->help, "", *value, value, NULL);
587:     } else if (nitem->dtype == PETSC_INT) {
588:       PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset);
589:       if (nitem->msize == 1) {
590:         PetscOptionsInt(name, nitem->help, "", *value, value, NULL);
591:       } else {
592:         n = nitem->msize;
593:         PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL);
594:       }
595:     } else if (nitem->dtype == PETSC_ENUM) {
596:       PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset);
597:       PetscInt   i     = 0;
598:       while (nitem->list[i++])
599:         ;
600:       PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL);
601:     } else if (nitem->dtype == PETSC_BOOL) {
602:       PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
603:       if (nitem->msize == 1) {
604:         PetscOptionsBool(name, nitem->help, "", *value, value, NULL);
605:       } else {
606:         n = nitem->msize;
607:         PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL);
608:       }
609:     }
610:     nitem = nitem->next;
611:   }
612:   PetscOptionsEnd();
613:   return 0;
614: }

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

619:    Collective

621:    Input Parameters:
622: +  bag - the bag of values
623: -  viewer - location to view the values

625:    Level: beginner

627:    Note:
628:    Currently PETSc bags saved in a binary file can only be read back
629:    in on a machine of the same architecture.

631: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
632:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
633:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
634: @*/
635: PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view)
636: {
637:   PetscBool    isascii, isbinary;
638:   PetscBagItem nitem = bag->bagitems;

642:   PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii);
643:   PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary);
644:   if (isascii) {
645:     if (bag->bagprefix) {
646:       PetscViewerASCIIPrintf(view, "PetscBag Object:  %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp);
647:     } else {
648:       PetscViewerASCIIPrintf(view, "PetscBag Object:  %s %s\n", bag->bagname, bag->baghelp);
649:     }
650:     while (nitem) {
651:       if (nitem->dtype == PETSC_CHAR) {
652:         char *value             = (char *)(((char *)bag) + nitem->offset);
653:         char  tmp               = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */
654:         value[nitem->msize - 1] = 0;
655:         PetscViewerASCIIPrintf(view, "  %s = %s; %s\n", nitem->name, value, nitem->help);
656:         value[nitem->msize - 1] = tmp;
657:       } else if (nitem->dtype == PETSC_REAL) {
658:         PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
659:         PetscInt   i;
660:         PetscViewerASCIIPrintf(view, "  %s = ", nitem->name);
661:         for (i = 0; i < nitem->msize; i++) PetscViewerASCIIPrintf(view, "%g ", (double)value[i]);
662:         PetscViewerASCIIPrintf(view, "; %s\n", nitem->help);
663:       } else if (nitem->dtype == PETSC_SCALAR) {
664:         PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset);
665: #if defined(PETSC_USE_COMPLEX)
666:         if ((double)PetscImaginaryPart(value)) {
667:           PetscViewerASCIIPrintf(view, "  %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help);
668:         } else {
669:           PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help);
670:         }
671: #else
672:         PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)value, nitem->help);
673: #endif
674:       } else if (nitem->dtype == PETSC_INT) {
675:         PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset);
676:         PetscViewerASCIIPrintf(view, "  %s = ", nitem->name);
677:         for (i = 0; i < nitem->msize; i++) PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i]);
678:         PetscViewerASCIIPrintf(view, "; %s\n", nitem->help);
679:       } else if (nitem->dtype == PETSC_BOOL) {
680:         PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
681:         PetscInt   i;
682:         /* some Fortran compilers use -1 as boolean */
683:         PetscViewerASCIIPrintf(view, "  %s = ", nitem->name);
684:         for (i = 0; i < nitem->msize; i++) {
685:           if (((int)value[i]) == -1) value[i] = PETSC_TRUE;
686:           /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
688:           PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]]);
689:         }
690:         PetscViewerASCIIPrintf(view, "; %s\n", nitem->help);
691:       } else if (nitem->dtype == PETSC_ENUM) {
692:         PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset);
693:         PetscInt  i     = 0;
694:         while (nitem->list[i++])
695:           ;
696:         PetscViewerASCIIPrintf(view, "  %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help);
697:       }
698:       nitem = nitem->next;
699:     }
700:   } else if (isbinary) {
701:     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
702:     PetscInt          deprecatedbagsize = 0;
703:     PetscViewerFormat format;
704:     PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT);
705:     PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT);
706:     PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT);
707:     PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR);
708:     PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR);
709:     while (nitem) {
710:       PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT);
711:       dtype = (PetscInt)nitem->dtype;
712:       PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT);
713:       PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR);
714:       PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR);
715:       PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT);
716:       /* some Fortran compilers use -1 as boolean */
717:       if (dtype == PETSC_BOOL && ((*(int *)(((char *)bag) + nitem->offset) == -1))) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE;

719:       PetscViewerBinaryWrite(view, (((char *)bag) + nitem->offset), nitem->msize, nitem->dtype);
720:       if (dtype == PETSC_ENUM) PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list);
721:       nitem = nitem->next;
722:     }
723:     PetscViewerGetFormat(view, &format);
724:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
725:       MPI_Comm comm;
726:       FILE    *info;
727:       PetscObjectGetComm((PetscObject)view, &comm);
728:       PetscViewerBinaryGetInfoPointer(view, &info);
729:       PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
730:       PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname);
731:       PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
732:     }
733:   }
734:   return 0;
735: }

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

740:   Collective

742:   Input Parameters:
743: + obj   - the object
744: . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
745: - optionname - option to activate viewing

747:   Level: intermediate

749: .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer`
750: @*/
751: PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[])
752: {
753:   static PetscBool  incall = PETSC_FALSE;
754:   PetscViewer       viewer;
755:   PetscViewerFormat format;
756:   const char       *prefix, *bprefix = NULL;
757:   PetscBool         flg;

759:   if (incall) return 0;
760:   incall = PETSC_TRUE;
762:   if (bobj) PetscObjectGetOptionsPrefix(bobj, &bprefix);
763:   prefix = bobj ? bprefix : bag->bagprefix;
764:   PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg);
765:   if (flg) {
766:     PetscViewerPushFormat(viewer, format);
767:     PetscBagView(bag, viewer);
768:     PetscViewerFlush(viewer);
769:     PetscViewerPopFormat(viewer);
770:     PetscViewerDestroy(&viewer);
771:   }
772:   incall = PETSC_FALSE;
773:   return 0;
774: }

776: /*@C
777:    PetscBagLoad - Loads a bag of values from a binary file

779:    Collective

781:    Input Parameters:
782: +  viewer - file to load values from
783: -  bag - the bag of values

785:    Note:
786:     You must have created and registered all the fields in the bag before loading into it.

788:    Level: beginner

790: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()`
791:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
792:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
793: @*/
794: PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag)
795: {
796:   PetscBool    isbinary;
797:   PetscInt     classid, bagcount, dtype, msize, offset, deprecatedbagsize;
798:   char         name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list;
799:   PetscBagItem nitem;
800:   MPI_Comm     comm;
801:   PetscMPIInt  flag;

805:   PetscObjectGetComm((PetscObject)view, &comm);
806:   MPI_Comm_compare(comm, bag->bagcomm, &flag);
808:   PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary);

811:   PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT);
813:   PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT);
814:   PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT);
816:   PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR);
817:   PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR);

819:   nitem = bag->bagitems;
820:   for (PetscInt i = 0; i < bagcount; i++) {
821:     PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT);
822:     /* ignore the offset in the file */
823:     PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT);
824:     PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR);
825:     PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR);
826:     PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT);

828:     if (dtype == (PetscInt)PETSC_CHAR) {
829:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR);
830:     } else if (dtype == (PetscInt)PETSC_REAL) {
831:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL);
832:     } else if (dtype == (PetscInt)PETSC_SCALAR) {
833:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR);
834:     } else if (dtype == (PetscInt)PETSC_INT) {
835:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT);
836:     } else if (dtype == (PetscInt)PETSC_BOOL) {
837:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL);
838:     } else if (dtype == (PetscInt)PETSC_ENUM) {
839:       PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM);
840:       PetscViewerBinaryReadStringArray(view, &list);
841:       /* don't need to save list because it is already registered in the bag */
842:       PetscFree(list);
843:     }
844:     nitem = nitem->next;
845:   }
846:   return 0;
847: }

849: /*@C
850:     PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files, can have values set from the
851:     options database

853:   Collective

855:   Level: Intermediate

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

861:   Output Parameter:
862: .   bag - the bag of values

864:    Notes:
865:    After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout

867:    The size of the A struct must be small enough to fit in a `PetscInt`; by default
868:    `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
869:    The warning about casting to a shorter length can be ignored below unless your A struct is too large

871: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
872:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
873:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
874: @*/
875: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
876: {
877:   const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar);

880:   PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize);
881:   PetscCalloc(totalsize, bag);

883:   (*bag)->bagsize        = totalsize;
884:   (*bag)->bagcomm        = comm;
885:   (*bag)->bagprefix      = NULL;
886:   (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar));
887:   return 0;
888: }

890: /*@C
891:     PetscBagSetName - Sets the name of a bag of values

893:   Not Collective

895:   Level: Intermediate

897:   Input Parameters:
898: +   bag - the bag of values
899: .   name - the name assigned to the bag
900: -   help - help message for bag

902: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
903:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
904:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
905: @*/
906: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
907: {
911:   PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1);
912:   PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1);
913:   return 0;
914: }

916: /*@C
917:     PetscBagGetName - Gets the name of a bag of values

919:   Not Collective

921:   Level: Intermediate

923:   Input Parameter:
924: .   bag - the bag of values

926:   Output Parameter:
927: .   name - the name assigned to the bag

929: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
930:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
931:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
932: @*/
933: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
934: {
937:   *name = bag->bagname;
938:   return 0;
939: }

941: /*@C
942:     PetscBagGetData - Gives back the user - access to memory that
943:     can be used for storing user-data-structure

945:   Not Collective

947:   Level: Intermediate

949:   Input Parameter:
950: .   bag - the bag of values

952:   Output Parameter:
953: .   data - pointer to memory that will have user-data-structure, this can be cast to a pointer of the type the C struct used in defining the bag

955: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`
956:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
957:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
958: @*/
959: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
960: {
963:   *data = bag->structlocation;
964:   return 0;
965: }

967: /*@C
968:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
969:   `PetscBag` items in the options database.

971:   Logically collective

973:   Level: Intermediate

975:   Input Parameters:
976: +   bag - the bag of values
977: -   prefix - the prefix to prepend all Bag item names with.

979:   NOTES: Must be called prior to registering any of the bag items.

981: .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
982:           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
983: @*/

985: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
986: {
988:   if (pre) {
991:     PetscFree(bag->bagprefix);
992:     PetscStrallocpy(pre, &(bag->bagprefix));
993:   } else PetscFree(bag->bagprefix);
994:   return 0;
995: }

997: /*@C
998:   PetscBagGetNames - Get the names of all entries in the bag

1000:   Not collective

1002:   Input Parameters:
1003: + bag   - the bag of values
1004: - names - array of the correct size to hold names, must be long enough to hold all the names

1006:   Output Parameter:
1007: . names - array of char pointers for names

1009:   Level: intermediate

1011: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()`
1012:           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
1013: @*/
1014: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1015: {
1016:   PetscBagItem nitem = bag->bagitems;

1020:   for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
1021:   return 0;
1022: }