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 `¶ms->dt`
30: . list - array of strings containing names of enum values followed by enum name followed by enum prefix
31: . mdefault - the initial value, cast with (`PetscEnum`)
32: - help - longer string with more information about the value
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 `¶ms->i`
85: . msize - number of entries in array
86: . name - name of the array
87: - help - longer string with more information about the value
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 `¶ms->d`
135: . msize - number of entries in the array
136: . name - name of the array
137: - help - longer string with more information about the value
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 `¶ms->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 `¶ms->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 `¶ms->b`
276: . msize - number of entries in array
277: . name - name of the boolean array
278: - help - longer string with more information about the value
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 `¶ms->mystring`
326: . msize - length of the string space in the struct
327: . mdefault - the initial value
328: . name - name of the string
329: - help - longer string with more information about the value
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 `¶ms->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 `¶ms->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 `¶ms->b`
468: . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
469: . name - name of the variable
470: - help - longer string with more information about the value
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: }