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: /*@
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 `¶ms->dt`
31: . list - array of strings containing names of enum values followed by enum name followed by enum prefix
32: . mdefault - the initial value, cast with (`PetscEnum`)
33: . name - the name of the item
34: - help - longer string with more information about the value
36: Level: beginner
38: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
39: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
40: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
41: @*/
42: PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help)
43: {
44: PetscBagItem item;
45: char nname[PETSC_BAG_NAME_LENGTH + 1];
46: PetscBool printhelp;
47: PetscInt i = 0;
49: PetscFunctionBegin;
50: PetscAssertPointer(bag, 1);
51: PetscAssertPointer(addr, 2);
52: PetscAssertPointer(list, 3);
53: PetscAssertPointer(name, 5);
54: PetscAssertPointer(help, 6);
55: nname[0] = '-';
56: nname[1] = 0;
57: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
58: /* bag options are registered outside a PetscOptionsBegin() block, so they name their manual section
59: here; "Bag" is the SUBMANSEC in the makefile of this directory */
60: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
61: if (printhelp) {
62: while (list[i++]);
63: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help));
64: for (i = 0; list[i + 2]; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " %s", list[i]));
65: PetscCall((*PetscHelpPrintf)(bag->bagcomm, "\n"));
66: }
67: PetscCall(PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL));
69: PetscCall(PetscNew(&item));
70: item->dtype = PETSC_ENUM;
71: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
72: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
73: item->next = NULL;
74: item->msize = 1;
75: PetscCall(PetscStrArrayallocpy(list, &item->list));
76: *(PetscEnum *)addr = mdefault;
77: PetscCall(PetscBagRegister_Private(bag, item, name, help));
78: PetscFunctionReturn(PETSC_SUCCESS);
79: }
81: /*@
82: PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag`
84: Logically Collective
86: Input Parameters:
87: + bag - the bag of values
88: . addr - location of integer in struct, for example `¶ms->i`
89: . msize - number of entries in array
90: . name - name of the array
91: - help - longer string with more information about the value
93: Level: beginner
95: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
96: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
97: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
98: @*/
99: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
100: {
101: PetscBagItem item;
102: char nname[PETSC_BAG_NAME_LENGTH + 1];
103: PetscBool printhelp;
104: PetscInt *values = (PetscInt *)addr;
105: PetscInt i, tmp = msize;
107: PetscFunctionBegin;
108: PetscAssertPointer(bag, 1);
109: PetscAssertPointer(addr, 2);
110: PetscAssertPointer(name, 4);
111: PetscAssertPointer(help, 5);
112: nname[0] = '-';
113: nname[1] = 0;
114: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
115: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
116: if (printhelp) {
117: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
118: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", values[i]));
119: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
120: }
121: PetscCall(PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
123: PetscCall(PetscNew(&item));
124: item->dtype = PETSC_INT;
125: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
126: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
127: item->next = NULL;
128: item->msize = msize;
129: PetscCall(PetscBagRegister_Private(bag, item, name, help));
130: PetscFunctionReturn(PETSC_SUCCESS);
131: }
133: /*@
134: PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag`
136: Logically Collective
138: Input Parameters:
139: + bag - the bag of values
140: . addr - location of real array in struct, for example `¶ms->d`
141: . msize - number of entries in the array
142: . name - name of the array
143: - help - longer string with more information about the value
145: Level: beginner
147: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
148: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
149: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
150: @*/
151: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
152: {
153: PetscBagItem item;
154: char nname[PETSC_BAG_NAME_LENGTH + 1];
155: PetscReal *values = (PetscReal *)addr;
156: PetscBool printhelp;
157: PetscInt i, tmp = msize;
159: PetscFunctionBegin;
160: PetscAssertPointer(bag, 1);
161: PetscAssertPointer(addr, 2);
162: PetscAssertPointer(name, 4);
163: PetscAssertPointer(help, 5);
164: nname[0] = '-';
165: nname[1] = 0;
166: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
167: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
168: if (printhelp) {
169: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
170: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)values[i]));
171: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
172: }
173: PetscCall(PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
175: PetscCall(PetscNew(&item));
176: item->dtype = PETSC_REAL;
177: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
178: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
179: item->next = NULL;
180: item->msize = msize;
181: PetscCall(PetscBagRegister_Private(bag, item, name, help));
182: PetscFunctionReturn(PETSC_SUCCESS);
183: }
185: /*@
186: PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag`
188: Logically Collective
190: Input Parameters:
191: + bag - the bag of values
192: . addr - location of integer in struct, for example `¶ms->i`
193: . mdefault - the initial value
194: . name - name of the integer
195: - help - longer string with more information about the value
197: Level: beginner
199: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
200: `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
201: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
202: @*/
203: PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help)
204: {
205: PetscBagItem item;
206: char nname[PETSC_BAG_NAME_LENGTH + 1];
207: PetscBool printhelp;
209: PetscFunctionBegin;
210: PetscAssertPointer(bag, 1);
211: PetscAssertPointer(addr, 2);
212: PetscAssertPointer(name, 4);
213: PetscAssertPointer(help, 5);
214: nname[0] = '-';
215: nname[1] = 0;
216: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
217: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
218: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
219: PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL));
221: PetscCall(PetscNew(&item));
222: item->dtype = PETSC_INT;
223: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
224: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
225: item->next = NULL;
226: item->msize = 1;
227: *(PetscInt *)addr = mdefault;
228: PetscCall(PetscBagRegister_Private(bag, item, name, help));
229: PetscFunctionReturn(PETSC_SUCCESS);
230: }
232: /*@
233: PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`
235: Logically Collective
237: Input Parameters:
238: + bag - the bag of values
239: . addr - location of integer in struct, for example `¶ms->i`
240: . mdefault - the initial value
241: . name - name of the integer
242: - help - longer string with more information about the value
244: Level: beginner
246: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
247: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
248: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
249: @*/
250: PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help)
251: {
252: PetscBagItem item;
253: char nname[PETSC_BAG_NAME_LENGTH + 1];
254: PetscBool printhelp;
255: PetscInt odefault;
256: PetscBool flg;
258: PetscFunctionBegin;
259: nname[0] = '-';
260: nname[1] = 0;
262: PetscCall(PetscIntCast(mdefault, &odefault));
263: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
264: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
265: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help));
266: PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg));
267: if (flg) mdefault = odefault;
269: PetscCall(PetscNew(&item));
270: item->dtype = PETSC_INT;
271: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
272: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
273: item->next = NULL;
274: item->msize = 1;
275: *(PetscInt64 *)addr = mdefault;
276: PetscCall(PetscBagRegister_Private(bag, item, name, help));
277: PetscFunctionReturn(PETSC_SUCCESS);
278: }
280: /*@
281: PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`
283: Logically Collective
285: Input Parameters:
286: + bag - the bag of values
287: . addr - location of boolean array in struct, for example `¶ms->b`
288: . msize - number of entries in array
289: . name - name of the boolean array
290: - help - longer string with more information about the value
292: Level: beginner
294: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
295: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
296: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
297: @*/
298: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
299: {
300: PetscBagItem item;
301: char nname[PETSC_BAG_NAME_LENGTH + 1];
302: PetscBool *values = (PetscBool *)addr;
303: PetscBool printhelp;
304: PetscInt i, tmp = msize;
306: PetscFunctionBegin;
307: PetscAssertPointer(bag, 1);
308: PetscAssertPointer(addr, 2);
309: PetscAssertPointer(name, 4);
310: PetscAssertPointer(help, 5);
311: nname[0] = '-';
312: nname[1] = 0;
313: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
314: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
315: if (printhelp) {
316: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
317: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", (PetscInt)values[i]));
318: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
319: }
320: PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
322: PetscCall(PetscNew(&item));
323: item->dtype = PETSC_BOOL;
324: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
325: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
326: item->next = NULL;
327: item->msize = msize;
328: PetscCall(PetscBagRegister_Private(bag, item, name, help));
329: PetscFunctionReturn(PETSC_SUCCESS);
330: }
332: /*@
333: PetscBagRegisterString - add a string value to a `PetscBag`
335: Logically Collective
337: Input Parameters:
338: + bag - the bag of values
339: . addr - location of start of string in struct, for example `¶ms->mystring`
340: . msize - length of the string space in the struct
341: . mdefault - the initial value
342: . name - name of the string
343: - help - longer string with more information about the value
345: Level: beginner
347: Note:
348: The struct must have the field char mystring[`msize`]; not char *mystring
350: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
351: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
352: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
353: @*/
354: PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help) PeNS
355: {
356: PetscBagItem item;
357: char nname[PETSC_BAG_NAME_LENGTH + 1];
358: PetscBool printhelp;
360: PetscFunctionBegin;
361: PetscAssertPointer(bag, 1);
362: PetscAssertPointer(addr, 2);
363: PetscAssertPointer(mdefault, 4);
364: PetscAssertPointer(name, 5);
365: PetscAssertPointer(help, 6);
366: nname[0] = '-';
367: nname[1] = 0;
368: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
369: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
370: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
372: PetscCall(PetscNew(&item));
373: item->dtype = PETSC_CHAR;
374: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
375: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
376: item->next = NULL;
377: item->msize = msize;
378: if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1));
379: PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL));
380: PetscCall(PetscBagRegister_Private(bag, item, name, help));
381: PetscFunctionReturn(PETSC_SUCCESS);
382: }
384: /*@
385: PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`
387: Logically Collective
389: Input Parameters:
390: + bag - the bag of values
391: . addr - location of `PetscReal` in struct, for example `¶ms->r`
392: . mdefault - the initial value
393: . name - name of the variable
394: - help - longer string with more information about the value
396: Level: beginner
398: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
399: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
400: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
401: @*/
402: PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help)
403: {
404: PetscBagItem item;
405: char nname[PETSC_BAG_NAME_LENGTH + 1];
406: PetscBool printhelp;
408: PetscFunctionBegin;
409: PetscAssertPointer(bag, 1);
410: PetscAssertPointer(addr, 2);
411: PetscAssertPointer(name, 4);
412: PetscAssertPointer(help, 5);
413: nname[0] = '-';
414: nname[1] = 0;
415: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
416: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
417: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help));
418: PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL));
420: PetscCall(PetscNew(&item));
421: item->dtype = PETSC_REAL;
422: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
423: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
424: item->next = NULL;
425: item->msize = 1;
426: *(PetscReal *)addr = mdefault;
427: PetscCall(PetscBagRegister_Private(bag, item, name, help));
428: PetscFunctionReturn(PETSC_SUCCESS);
429: }
431: /*@
432: PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`
434: Logically Collective
436: Input Parameters:
437: + bag - the bag of values
438: . addr - location of `PetscScalar` in struct, for example `¶ms->c`
439: . mdefault - the initial value
440: . name - name of the variable
441: - help - longer string with more information about the value
443: Level: beginner
445: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
446: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagSetFromOptions()`,
447: `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
448: @*/
449: PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help)
450: {
451: PetscBagItem item;
452: char nname[PETSC_BAG_NAME_LENGTH + 1];
453: PetscBool printhelp;
455: PetscFunctionBegin;
456: PetscAssertPointer(bag, 1);
457: PetscAssertPointer(addr, 2);
458: PetscAssertPointer(name, 4);
459: PetscAssertPointer(help, 5);
460: nname[0] = '-';
461: nname[1] = 0;
462: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
463: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
464: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help));
465: PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL));
467: PetscCall(PetscNew(&item));
468: item->dtype = PETSC_SCALAR;
469: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
470: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
471: item->next = NULL;
472: item->msize = 1;
473: *(PetscScalar *)addr = mdefault;
474: PetscCall(PetscBagRegister_Private(bag, item, name, help));
475: PetscFunctionReturn(PETSC_SUCCESS);
476: }
478: /*@
479: PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`
481: Logically Collective
483: Input Parameters:
484: + bag - the bag of values
485: . addr - location of `PetscBool` in struct, for example `¶ms->b`
486: . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
487: . name - name of the variable
488: - help - longer string with more information about the value
490: Level: beginner
492: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
493: `PetscBagRegisterInt()`, `PetscBagRegisterScalar()`,
494: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
495: @*/
496: PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help)
497: {
498: PetscBagItem item;
499: char nname[PETSC_BAG_NAME_LENGTH + 1];
500: PetscBool printhelp;
502: PetscFunctionBegin;
503: PetscAssertPointer(bag, 1);
504: PetscAssertPointer(addr, 2);
505: PetscAssertPointer(name, 4);
506: PetscAssertPointer(help, 5);
507: nname[0] = '-';
508: nname[1] = 0;
509: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
510: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
511: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help));
512: PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL));
514: PetscCall(PetscNew(&item));
515: item->dtype = PETSC_BOOL;
516: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
517: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
518: item->next = NULL;
519: item->msize = 1;
520: *(PetscBool *)addr = mdefault;
521: PetscCall(PetscBagRegister_Private(bag, item, name, help));
522: PetscFunctionReturn(PETSC_SUCCESS);
523: }
525: /*@
526: PetscBagDestroy - Destroys a `PetscBag`
528: Collective
530: Input Parameter:
531: . bag - the bag of values
533: Level: beginner
535: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
536: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
537: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
538: @*/
539: PetscErrorCode PetscBagDestroy(PetscBag *bag)
540: {
541: PetscBagItem nitem;
543: PetscFunctionBegin;
544: if (!*bag) PetscFunctionReturn(PETSC_SUCCESS);
545: PetscAssertPointer(*bag, 1);
546: nitem = (*bag)->bagitems;
547: while (nitem) {
548: PetscBagItem item = nitem->next;
550: PetscCall(PetscStrArrayDestroy(&nitem->list));
551: PetscCall(PetscFree(nitem));
552: nitem = item;
553: }
554: PetscCall(PetscFree((*bag)->bagprefix));
555: PetscCall(PetscFree(*bag));
556: PetscFunctionReturn(PETSC_SUCCESS);
557: }
559: /*@
560: PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database
562: Collective
564: Input Parameter:
565: . bag - the bag of values
567: Level: beginner
569: Note:
570: The options database keys for the entries are of the form `-[bagprefix]_name value`
572: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`,
573: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
574: `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()`
575: @*/
576: PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
577: {
578: PetscBagItem nitem = bag->bagitems;
579: char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3];
580: PetscInt n;
582: PetscFunctionBegin;
583: PetscAssertPointer(bag, 1);
584: PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname)));
585: PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname)));
586: PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname)));
587: PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, "Bag");
588: while (nitem) {
589: name[0] = '-';
590: name[1] = 0;
591: PetscCall(PetscStrlcat(name, nitem->name, sizeof(name)));
592: if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
593: char *value = ((char *)bag) + nitem->offset;
594: PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL));
595: } else if (nitem->dtype == PETSC_REAL) {
596: PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
597: if (nitem->msize == 1) PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL));
598: else {
599: n = nitem->msize;
600: PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL));
601: }
602: } else if (nitem->dtype == PETSC_SCALAR) {
603: PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset);
604: PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL));
605: } else if (nitem->dtype == PETSC_INT) {
606: PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset);
607: if (nitem->msize == 1) PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL));
608: else {
609: n = nitem->msize;
610: PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL));
611: }
612: } else if (nitem->dtype == PETSC_ENUM) {
613: PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset);
614: PetscInt i = 0;
615: while (nitem->list[i++]);
616: PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL));
617: } else if (nitem->dtype == PETSC_BOOL) {
618: PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
619: if (nitem->msize == 1) PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL));
620: else {
621: n = nitem->msize;
622: PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL));
623: }
624: }
625: nitem = nitem->next;
626: }
627: PetscOptionsEnd();
628: PetscFunctionReturn(PETSC_SUCCESS);
629: }
631: /*@
632: PetscBagView - Views a bag of values as either ASCII text or a binary file
634: Collective
636: Input Parameters:
637: + bag - the bag of values
638: - view - location to view the values
640: Level: beginner
642: Note:
643: Currently PETSc bags saved in a binary file can only be read back
644: in on a machine with the same binary format.
646: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`,
647: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`,
648: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
649: @*/
650: PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view)
651: {
652: PetscBool isascii, isbinary;
653: PetscBagItem nitem = bag->bagitems;
655: PetscFunctionBegin;
656: PetscAssertPointer(bag, 1);
658: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii));
659: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
660: if (isascii) {
661: if (bag->bagprefix) {
662: PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp));
663: } else {
664: PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp));
665: }
666: while (nitem) {
667: if (nitem->dtype == PETSC_CHAR) {
668: char *value = ((char *)bag) + nitem->offset;
669: char tmp = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */
670: value[nitem->msize - 1] = 0;
671: PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help));
672: value[nitem->msize - 1] = tmp;
673: } else if (nitem->dtype == PETSC_REAL) {
674: PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
675: PetscInt i;
676: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
677: for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i]));
678: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
679: } else if (nitem->dtype == PETSC_SCALAR) {
680: PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset);
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 if (nitem->dtype == PETSC_INT) {
687: PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset);
688: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
689: for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i]));
690: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
691: } else if (nitem->dtype == PETSC_BOOL) {
692: PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
693: PetscInt i;
694: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
695: for (i = 0; i < nitem->msize; i++) {
696: /* stdbool.h defines true=1 and false=0, but non-conformant Fortran compilers define .true.=0xff (-1 if signed, 255 if unsigned).
697: with the checks for either PETSC_FALSE or PETSC_TRUE we truly demand that the value be 0 or 1 */
698: 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]);
699: PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]]));
700: }
701: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
702: } else if (nitem->dtype == PETSC_ENUM) {
703: PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset);
704: PetscInt i = 0;
705: while (nitem->list[i++]);
706: PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help));
707: }
708: nitem = nitem->next;
709: }
710: } else if (isbinary) {
711: PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype;
712: PetscInt deprecatedbagsize = 0;
713: PetscViewerFormat format;
714: PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT));
715: PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT));
716: PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT));
717: PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
718: PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
719: while (nitem) {
720: PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT));
721: dtype = (PetscInt)nitem->dtype;
722: PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT));
723: PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
724: PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
725: PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT));
727: PetscCall(PetscViewerBinaryWrite(view, (char *)bag + nitem->offset, nitem->msize, nitem->dtype));
728: if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list));
729: nitem = nitem->next;
730: }
731: PetscCall(PetscViewerGetFormat(view, &format));
732: if (format == PETSC_VIEWER_BINARY_MATLAB) {
733: MPI_Comm comm;
734: FILE *info;
735: PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
736: PetscCall(PetscViewerBinaryGetInfoPointer(view, &info));
737: PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n"));
738: PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname));
739: PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n"));
740: }
741: }
742: PetscFunctionReturn(PETSC_SUCCESS);
743: }
745: /*@
746: PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed.
748: Collective
750: Input Parameters:
751: + bag - the object
752: . bobj - optional other object that provides prefix (if `NULL` then the prefix in obj is used)
753: - name - option to activate viewing
755: Options Database Key:
756: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`
758: Level: intermediate
760: Note:
761: This checks the options database, creates the viewer on-the-fly, uses it and then destroys it. Hence it should not be called in heavily used routines,
762: rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.
764: .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer`, `PetscBagView()`, `PetscObjectViewFromOptions()`, `PetscOptionsCreateViewer()`
765: @*/
766: PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char name[])
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;
777: PetscAssertPointer(bag, 1);
778: if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix));
779: prefix = bobj ? bprefix : bag->bagprefix;
780: PetscCall(PetscOptionsCreateViewer(bag->bagcomm, NULL, prefix, name, &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: /*@
793: PetscBagLoad - Loads a bag of values from a binary file
795: Collective
797: Input Parameters:
798: + view - 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;
821: PetscAssertPointer(bag, 2);
822: PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
823: PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag));
824: PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag");
825: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
826: PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type");
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 %" PetscInt_FMT " then passed in bag %" PetscInt_FMT, bagcount, 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: /*@
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 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 struct is too large
888: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
889: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
890: `PetscBagSetFromOptions()`, `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;
897: PetscAssertPointer(bag, 3);
899: PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize));
900: PetscCall(PetscCalloc(totalsize, bag));
901: PetscCall(PetscIntCast(totalsize, &(*bag)->bagsize));
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: /*@
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;
927: PetscAssertPointer(bag, 1);
928: PetscAssertPointer(name, 2);
929: PetscAssertPointer(help, 3);
930: PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1));
931: PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1));
932: PetscFunctionReturn(PETSC_SUCCESS);
933: }
935: /*@
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, const char *name[])
953: {
954: PetscFunctionBegin;
955: PetscAssertPointer(bag, 1);
956: PetscAssertPointer(name, 2);
957: *name = bag->bagname;
958: PetscFunctionReturn(PETSC_SUCCESS);
959: }
961: /*@
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, PetscCtxRt data)
981: {
982: PetscFunctionBegin;
983: PetscAssertPointer(bag, 1);
984: PetscAssertPointer(data, 2);
985: *(void **)data = bag->structlocation;
986: PetscFunctionReturn(PETSC_SUCCESS);
987: }
989: /*@
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: - pre - 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: @*/
1007: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1008: {
1009: PetscFunctionBegin;
1010: PetscAssertPointer(bag, 1);
1011: if (pre) {
1012: PetscAssertPointer(pre, 2);
1013: PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen");
1014: PetscCall(PetscFree(bag->bagprefix));
1015: PetscCall(PetscStrallocpy(pre, &bag->bagprefix));
1016: } else PetscCall(PetscFree(bag->bagprefix));
1017: PetscFunctionReturn(PETSC_SUCCESS);
1018: }
1020: /*@
1021: PetscBagGetNames - Get the names of all entries in the bag
1023: Not Collective
1025: Input Parameter:
1026: . bag - the bag of values
1028: Output Parameter:
1029: . names - pass in an array of char pointers to hold the names. The array must be as long as the number of items in the bag.
1031: Level: intermediate
1033: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()`,
1034: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
1035: @*/
1036: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1037: {
1038: PetscBagItem nitem = bag->bagitems;
1040: PetscFunctionBegin;
1041: PetscAssertPointer(bag, 1);
1042: PetscAssertPointer(names, 2);
1043: for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
1044: PetscFunctionReturn(PETSC_SUCCESS);
1045: }