Actual source code: bag.c
1: #include <petsc/private/petscimpl.h>
2: #include <petsc/private/bagimpl.h>
4: /*
5: Adds item to the linked list in a bag
6: */
7: static PetscErrorCode PetscBagRegister_Private(PetscBag bag, PetscBagItem item, const char *name, const char *help)
8: {
9: PetscFunctionBegin;
10: PetscCall(PetscStrncpy(item->name, name, PETSC_BAG_NAME_LENGTH - 1));
11: PetscCall(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: PetscFunctionReturn(PETSC_SUCCESS);
20: }
22: /*@
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: . name - the name of the item
33: - help - longer string with more information about the value
35: Level: beginner
37: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
38: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
39: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
40: @*/
41: PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help)
42: {
43: PetscBagItem item;
44: char nname[PETSC_BAG_NAME_LENGTH + 1];
45: PetscBool printhelp;
46: PetscInt i = 0;
48: PetscFunctionBegin;
49: PetscAssertPointer(bag, 1);
50: PetscAssertPointer(addr, 2);
51: PetscAssertPointer(list, 3);
52: PetscAssertPointer(name, 5);
53: PetscAssertPointer(help, 6);
54: nname[0] = '-';
55: nname[1] = 0;
56: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
57: /* bag options are registered outside a PetscOptionsBegin() block, so they name their manual section
58: here; "Bag" is the SUBMANSEC in the makefile of this directory */
59: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
60: if (printhelp) {
61: while (list[i++]);
62: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help));
63: for (i = 0; list[i + 2]; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " %s", list[i]));
64: PetscCall((*PetscHelpPrintf)(bag->bagcomm, "\n"));
65: }
66: PetscCall(PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL));
68: PetscCall(PetscNew(&item));
69: item->dtype = PETSC_ENUM;
70: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
71: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
72: item->next = NULL;
73: item->msize = 1;
74: PetscCall(PetscStrArrayallocpy(list, &item->list));
75: *(PetscEnum *)addr = mdefault;
76: PetscCall(PetscBagRegister_Private(bag, item, name, help));
77: PetscFunctionReturn(PETSC_SUCCESS);
78: }
80: /*@
81: PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag`
83: Logically Collective
85: Input Parameters:
86: + bag - the bag of values
87: . addr - location of integer in struct, for example `¶ms->i`
88: . msize - number of entries in array
89: . name - name of the array
90: - help - longer string with more information about the value
92: Level: beginner
94: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
95: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
96: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
97: @*/
98: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
99: {
100: PetscBagItem item;
101: char nname[PETSC_BAG_NAME_LENGTH + 1];
102: PetscBool printhelp;
103: PetscInt *values = (PetscInt *)addr;
104: PetscInt i, tmp = msize;
106: PetscFunctionBegin;
107: PetscAssertPointer(bag, 1);
108: PetscAssertPointer(addr, 2);
109: PetscAssertPointer(name, 4);
110: PetscAssertPointer(help, 5);
111: nname[0] = '-';
112: nname[1] = 0;
113: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
114: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
115: if (printhelp) {
116: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
117: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", values[i]));
118: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
119: }
120: PetscCall(PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
122: PetscCall(PetscNew(&item));
123: item->dtype = PETSC_INT;
124: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
125: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
126: item->next = NULL;
127: item->msize = msize;
128: PetscCall(PetscBagRegister_Private(bag, item, name, help));
129: PetscFunctionReturn(PETSC_SUCCESS);
130: }
132: /*@
133: PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag`
135: Logically Collective
137: Input Parameters:
138: + bag - the bag of values
139: . addr - location of real array in struct, for example `¶ms->d`
140: . msize - number of entries in the array
141: . name - name of the array
142: - help - longer string with more information about the value
144: Level: beginner
146: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
147: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
148: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
149: @*/
150: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
151: {
152: PetscBagItem item;
153: char nname[PETSC_BAG_NAME_LENGTH + 1];
154: PetscReal *values = (PetscReal *)addr;
155: PetscBool printhelp;
156: PetscInt i, tmp = msize;
158: PetscFunctionBegin;
159: PetscAssertPointer(bag, 1);
160: PetscAssertPointer(addr, 2);
161: PetscAssertPointer(name, 4);
162: PetscAssertPointer(help, 5);
163: nname[0] = '-';
164: nname[1] = 0;
165: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
166: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
167: if (printhelp) {
168: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
169: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)values[i]));
170: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
171: }
172: PetscCall(PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
174: PetscCall(PetscNew(&item));
175: item->dtype = PETSC_REAL;
176: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
177: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
178: item->next = NULL;
179: item->msize = msize;
180: PetscCall(PetscBagRegister_Private(bag, item, name, help));
181: PetscFunctionReturn(PETSC_SUCCESS);
182: }
184: /*@
185: PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag`
187: Logically Collective
189: Input Parameters:
190: + bag - the bag of values
191: . addr - location of integer in struct, for example `¶ms->i`
192: . mdefault - the initial value
193: . name - name of the integer
194: - help - longer string with more information about the value
196: Level: beginner
198: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
199: `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
200: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
201: @*/
202: PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help)
203: {
204: PetscBagItem item;
205: char nname[PETSC_BAG_NAME_LENGTH + 1];
206: PetscBool printhelp;
208: PetscFunctionBegin;
209: PetscAssertPointer(bag, 1);
210: PetscAssertPointer(addr, 2);
211: PetscAssertPointer(name, 4);
212: PetscAssertPointer(help, 5);
213: nname[0] = '-';
214: nname[1] = 0;
215: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
216: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
217: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
218: PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL));
220: PetscCall(PetscNew(&item));
221: item->dtype = PETSC_INT;
222: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
223: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
224: item->next = NULL;
225: item->msize = 1;
226: *(PetscInt *)addr = mdefault;
227: PetscCall(PetscBagRegister_Private(bag, item, name, help));
228: PetscFunctionReturn(PETSC_SUCCESS);
229: }
231: /*@
232: PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`
234: Logically Collective
236: Input Parameters:
237: + bag - the bag of values
238: . addr - location of integer in struct, for example `¶ms->i`
239: . mdefault - the initial value
240: . name - name of the integer
241: - help - longer string with more information about the value
243: Level: beginner
245: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
246: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
247: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
248: @*/
249: PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help)
250: {
251: PetscBagItem item;
252: char nname[PETSC_BAG_NAME_LENGTH + 1];
253: PetscBool printhelp;
254: PetscInt odefault;
255: PetscBool flg;
257: PetscFunctionBegin;
258: nname[0] = '-';
259: nname[1] = 0;
261: PetscCall(PetscIntCast(mdefault, &odefault));
262: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
263: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
264: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help));
265: PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg));
266: if (flg) mdefault = odefault;
268: PetscCall(PetscNew(&item));
269: item->dtype = PETSC_INT;
270: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
271: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
272: item->next = NULL;
273: item->msize = 1;
274: *(PetscInt64 *)addr = mdefault;
275: PetscCall(PetscBagRegister_Private(bag, item, name, help));
276: PetscFunctionReturn(PETSC_SUCCESS);
277: }
279: /*@
280: PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`
282: Logically Collective
284: Input Parameters:
285: + bag - the bag of values
286: . addr - location of boolean array in struct, for example `¶ms->b`
287: . msize - number of entries in array
288: . name - name of the boolean array
289: - help - longer string with more information about the value
291: Level: beginner
293: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
294: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
295: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
296: @*/
297: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
298: {
299: PetscBagItem item;
300: char nname[PETSC_BAG_NAME_LENGTH + 1];
301: PetscBool *values = (PetscBool *)addr;
302: PetscBool printhelp;
303: PetscInt i, tmp = msize;
305: PetscFunctionBegin;
306: PetscAssertPointer(bag, 1);
307: PetscAssertPointer(addr, 2);
308: PetscAssertPointer(name, 4);
309: PetscAssertPointer(help, 5);
310: nname[0] = '-';
311: nname[1] = 0;
312: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
313: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
314: if (printhelp) {
315: PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
316: for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", (PetscInt)values[i]));
317: PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
318: }
319: PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, values, &tmp, NULL));
321: PetscCall(PetscNew(&item));
322: item->dtype = PETSC_BOOL;
323: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
324: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
325: item->next = NULL;
326: item->msize = msize;
327: PetscCall(PetscBagRegister_Private(bag, item, name, help));
328: PetscFunctionReturn(PETSC_SUCCESS);
329: }
331: /*@
332: PetscBagRegisterString - add a string value to a `PetscBag`
334: Logically Collective
336: Input Parameters:
337: + bag - the bag of values
338: . addr - location of start of string in struct, for example `¶ms->mystring`
339: . msize - length of the string space in the struct
340: . mdefault - the initial value
341: . name - name of the string
342: - help - longer string with more information about the value
344: Level: beginner
346: Note:
347: The struct must have the field char mystring[`msize`]; not char *mystring
349: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
350: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
351: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
352: @*/
353: PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help) PeNS
354: {
355: PetscBagItem item;
356: char nname[PETSC_BAG_NAME_LENGTH + 1];
357: PetscBool printhelp;
359: PetscFunctionBegin;
360: PetscAssertPointer(bag, 1);
361: PetscAssertPointer(addr, 2);
362: PetscAssertPointer(mdefault, 4);
363: PetscAssertPointer(name, 5);
364: PetscAssertPointer(help, 6);
365: nname[0] = '-';
366: nname[1] = 0;
367: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
368: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
369: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
371: PetscCall(PetscNew(&item));
372: item->dtype = PETSC_CHAR;
373: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
374: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
375: item->next = NULL;
376: item->msize = msize;
377: if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1));
378: PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL));
379: PetscCall(PetscBagRegister_Private(bag, item, name, help));
380: PetscFunctionReturn(PETSC_SUCCESS);
381: }
383: /*@
384: PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`
386: Logically Collective
388: Input Parameters:
389: + bag - the bag of values
390: . addr - location of `PetscReal` in struct, for example `¶ms->r`
391: . mdefault - the initial value
392: . name - name of the variable
393: - help - longer string with more information about the value
395: Level: beginner
397: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
398: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
399: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
400: @*/
401: PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help)
402: {
403: PetscBagItem item;
404: char nname[PETSC_BAG_NAME_LENGTH + 1];
405: PetscBool printhelp;
407: PetscFunctionBegin;
408: PetscAssertPointer(bag, 1);
409: PetscAssertPointer(addr, 2);
410: PetscAssertPointer(name, 4);
411: PetscAssertPointer(help, 5);
412: nname[0] = '-';
413: nname[1] = 0;
414: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
415: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
416: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help));
417: PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL));
419: PetscCall(PetscNew(&item));
420: item->dtype = PETSC_REAL;
421: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
422: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
423: item->next = NULL;
424: item->msize = 1;
425: *(PetscReal *)addr = mdefault;
426: PetscCall(PetscBagRegister_Private(bag, item, name, help));
427: PetscFunctionReturn(PETSC_SUCCESS);
428: }
430: /*@
431: PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`
433: Logically Collective
435: Input Parameters:
436: + bag - the bag of values
437: . addr - location of `PetscScalar` in struct, for example `¶ms->c`
438: . mdefault - the initial value
439: . name - name of the variable
440: - help - longer string with more information about the value
442: Level: beginner
444: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
445: `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagSetFromOptions()`,
446: `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
447: @*/
448: PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help)
449: {
450: PetscBagItem item;
451: char nname[PETSC_BAG_NAME_LENGTH + 1];
452: PetscBool printhelp;
454: PetscFunctionBegin;
455: PetscAssertPointer(bag, 1);
456: PetscAssertPointer(addr, 2);
457: PetscAssertPointer(name, 4);
458: PetscAssertPointer(help, 5);
459: nname[0] = '-';
460: nname[1] = 0;
461: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
462: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
463: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help));
464: PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL));
466: PetscCall(PetscNew(&item));
467: item->dtype = PETSC_SCALAR;
468: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
469: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
470: item->next = NULL;
471: item->msize = 1;
472: *(PetscScalar *)addr = mdefault;
473: PetscCall(PetscBagRegister_Private(bag, item, name, help));
474: PetscFunctionReturn(PETSC_SUCCESS);
475: }
477: /*@
478: PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`
480: Logically Collective
482: Input Parameters:
483: + bag - the bag of values
484: . addr - location of `PetscBool` in struct, for example `¶ms->b`
485: . mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
486: . name - name of the variable
487: - help - longer string with more information about the value
489: Level: beginner
491: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
492: `PetscBagRegisterInt()`, `PetscBagRegisterScalar()`,
493: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
494: @*/
495: PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help)
496: {
497: PetscBagItem item;
498: char nname[PETSC_BAG_NAME_LENGTH + 1];
499: PetscBool printhelp;
501: PetscFunctionBegin;
502: PetscAssertPointer(bag, 1);
503: PetscAssertPointer(addr, 2);
504: PetscAssertPointer(name, 4);
505: PetscAssertPointer(help, 5);
506: nname[0] = '-';
507: nname[1] = 0;
508: PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
509: PetscCall(PetscOptionsHelpPrintable_Internal(NULL, "Bag", &printhelp));
510: if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help));
511: PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL));
513: PetscCall(PetscNew(&item));
514: item->dtype = PETSC_BOOL;
515: item->offset = (PetscInt)(((size_t)addr) - ((size_t)bag));
516: PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
517: item->next = NULL;
518: item->msize = 1;
519: *(PetscBool *)addr = mdefault;
520: PetscCall(PetscBagRegister_Private(bag, item, name, help));
521: PetscFunctionReturn(PETSC_SUCCESS);
522: }
524: /*@
525: PetscBagDestroy - Destroys a `PetscBag`
527: Collective
529: Input Parameter:
530: . bag - the bag of values
532: Level: beginner
534: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
535: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
536: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
537: @*/
538: PetscErrorCode PetscBagDestroy(PetscBag *bag)
539: {
540: PetscBagItem nitem;
542: PetscFunctionBegin;
543: if (!*bag) PetscFunctionReturn(PETSC_SUCCESS);
544: PetscAssertPointer(*bag, 1);
545: nitem = (*bag)->bagitems;
546: while (nitem) {
547: PetscBagItem item = nitem->next;
549: PetscCall(PetscStrArrayDestroy(&nitem->list));
550: PetscCall(PetscFree(nitem));
551: nitem = item;
552: }
553: PetscCall(PetscFree((*bag)->bagprefix));
554: PetscCall(PetscFree(*bag));
555: PetscFunctionReturn(PETSC_SUCCESS);
556: }
558: /*@
559: PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database
561: Collective
563: Input Parameter:
564: . bag - the bag of values
566: Level: beginner
568: Note:
569: The options database keys for the entries are of the form `-[bagprefix]_name value`
571: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`,
572: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
573: `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()`
574: @*/
575: PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
576: {
577: PetscBagItem nitem = bag->bagitems;
578: char name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3];
579: PetscInt n;
581: PetscFunctionBegin;
582: PetscAssertPointer(bag, 1);
583: PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname)));
584: PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname)));
585: PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname)));
586: PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, "Bag");
587: while (nitem) {
588: name[0] = '-';
589: name[1] = 0;
590: PetscCall(PetscStrlcat(name, nitem->name, sizeof(name)));
591: if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
592: char *value = ((char *)bag) + nitem->offset;
593: PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL));
594: } else if (nitem->dtype == PETSC_REAL) {
595: PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
596: if (nitem->msize == 1) PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL));
597: else {
598: n = nitem->msize;
599: PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL));
600: }
601: } else if (nitem->dtype == PETSC_SCALAR) {
602: PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset);
603: PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL));
604: } else if (nitem->dtype == PETSC_INT) {
605: PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset);
606: if (nitem->msize == 1) PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL));
607: else {
608: n = nitem->msize;
609: PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL));
610: }
611: } else if (nitem->dtype == PETSC_ENUM) {
612: PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset);
613: PetscInt i = 0;
614: while (nitem->list[i++]);
615: PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL));
616: } else if (nitem->dtype == PETSC_BOOL) {
617: PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
618: if (nitem->msize == 1) PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL));
619: else {
620: n = nitem->msize;
621: PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL));
622: }
623: }
624: nitem = nitem->next;
625: }
626: PetscOptionsEnd();
627: PetscFunctionReturn(PETSC_SUCCESS);
628: }
630: /*@
631: PetscBagView - Views a bag of values as either ASCII text or a binary file
633: Collective
635: Input Parameters:
636: + bag - the bag of values
637: - view - location to view the values
639: Level: beginner
641: Note:
642: Currently PETSc bags saved in a binary file can only be read back
643: in on a machine with the same binary format.
645: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`,
646: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`,
647: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
648: @*/
649: PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view)
650: {
651: PetscBool isascii, isbinary;
652: PetscBagItem nitem = bag->bagitems;
654: PetscFunctionBegin;
655: PetscAssertPointer(bag, 1);
657: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii));
658: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
659: if (isascii) {
660: if (bag->bagprefix) {
661: PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp));
662: } else {
663: PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object: %s %s\n", bag->bagname, bag->baghelp));
664: }
665: while (nitem) {
666: if (nitem->dtype == PETSC_CHAR) {
667: char *value = ((char *)bag) + nitem->offset;
668: char tmp = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */
669: value[nitem->msize - 1] = 0;
670: PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; %s\n", nitem->name, value, nitem->help));
671: value[nitem->msize - 1] = tmp;
672: } else if (nitem->dtype == PETSC_REAL) {
673: PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
674: PetscInt i;
675: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
676: for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i]));
677: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
678: } else if (nitem->dtype == PETSC_SCALAR) {
679: PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset);
680: if ((double)PetscImaginaryPart(value)) {
681: PetscCall(PetscViewerASCIIPrintf(view, " %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help));
682: } else {
683: PetscCall(PetscViewerASCIIPrintf(view, " %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help));
684: }
685: } else if (nitem->dtype == PETSC_INT) {
686: PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset);
687: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
688: for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i]));
689: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
690: } else if (nitem->dtype == PETSC_BOOL) {
691: PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
692: PetscInt i;
693: PetscCall(PetscViewerASCIIPrintf(view, " %s = ", nitem->name));
694: for (i = 0; i < nitem->msize; i++) {
695: /* stdbool.h defines true=1 and false=0, but non-conformant Fortran compilers define .true.=0xff (-1 if signed, 255 if unsigned).
696: with the checks for either PETSC_FALSE or PETSC_TRUE we truly demand that the value be 0 or 1 */
697: 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]);
698: PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]]));
699: }
700: PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
701: } else if (nitem->dtype == PETSC_ENUM) {
702: PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset);
703: PetscInt i = 0;
704: while (nitem->list[i++]);
705: PetscCall(PetscViewerASCIIPrintf(view, " %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help));
706: }
707: nitem = nitem->next;
708: }
709: } else if (isbinary) {
710: PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype;
711: PetscInt deprecatedbagsize = 0;
712: PetscViewerFormat format;
713: PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT));
714: PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT));
715: PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT));
716: PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
717: PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
718: while (nitem) {
719: PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT));
720: dtype = (PetscInt)nitem->dtype;
721: PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT));
722: PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
723: PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
724: PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT));
726: PetscCall(PetscViewerBinaryWrite(view, (char *)bag + nitem->offset, nitem->msize, nitem->dtype));
727: if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list));
728: nitem = nitem->next;
729: }
730: PetscCall(PetscViewerGetFormat(view, &format));
731: if (format == PETSC_VIEWER_BINARY_MATLAB) {
732: MPI_Comm comm;
733: FILE *info;
734: PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
735: PetscCall(PetscViewerBinaryGetInfoPointer(view, &info));
736: PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n"));
737: PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname));
738: PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n"));
739: }
740: }
741: PetscFunctionReturn(PETSC_SUCCESS);
742: }
744: /*@
745: PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed.
747: Collective
749: Input Parameters:
750: + bag - the object
751: . bobj - optional other object that provides prefix (if `NULL` then the prefix in obj is used)
752: - name - option to activate viewing
754: Options Database Key:
755: . -name viewer_specification - See `PetscOptionsCreateViewer()` for the values of `viewer_specification`
757: Level: intermediate
759: Note:
760: 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,
761: rather `PetscOptionsCreateViewer()` should be used to construct the viewer once which can then be utilized in the heavily used routine.
763: .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer`, `PetscBagView()`, `PetscObjectViewFromOptions()`, `PetscOptionsCreateViewer()`
764: @*/
765: PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char name[])
766: {
767: static PetscBool incall = PETSC_FALSE;
768: PetscViewer viewer;
769: PetscViewerFormat format;
770: const char *prefix, *bprefix = NULL;
771: PetscBool flg;
773: PetscFunctionBegin;
774: if (incall) PetscFunctionReturn(PETSC_SUCCESS);
775: incall = PETSC_TRUE;
776: PetscAssertPointer(bag, 1);
777: if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix));
778: prefix = bobj ? bprefix : bag->bagprefix;
779: PetscCall(PetscOptionsCreateViewer(bag->bagcomm, NULL, prefix, name, &viewer, &format, &flg));
780: if (flg) {
781: PetscCall(PetscViewerPushFormat(viewer, format));
782: PetscCall(PetscBagView(bag, viewer));
783: PetscCall(PetscViewerFlush(viewer));
784: PetscCall(PetscViewerPopFormat(viewer));
785: PetscCall(PetscViewerDestroy(&viewer));
786: }
787: incall = PETSC_FALSE;
788: PetscFunctionReturn(PETSC_SUCCESS);
789: }
791: /*@
792: PetscBagLoad - Loads a bag of values from a binary file
794: Collective
796: Input Parameters:
797: + view - file to load values from
798: - bag - the bag of values
800: Level: beginner
802: Note:
803: You must have created and registered all the fields in the bag before loading into it. This only loads values.
805: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()`,
806: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
807: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
808: @*/
809: PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag)
810: {
811: PetscBool isbinary;
812: PetscInt classid, bagcount, dtype, msize, offset, deprecatedbagsize;
813: char name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list;
814: PetscBagItem nitem;
815: MPI_Comm comm;
816: PetscMPIInt flag;
818: PetscFunctionBegin;
820: PetscAssertPointer(bag, 2);
821: PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
822: PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag));
823: PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag");
824: PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
825: PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type");
827: PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT));
828: PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file");
829: PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT));
830: PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT));
831: PetscCheck(bagcount == bag->count, comm, PETSC_ERR_ARG_INCOMP, "Bag in file has different number of entries %" PetscInt_FMT " then passed in bag %" PetscInt_FMT, bagcount, bag->count);
832: PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
833: PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
835: nitem = bag->bagitems;
836: for (PetscInt i = 0; i < bagcount; i++) {
837: PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT));
838: /* ignore the offset in the file */
839: PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT));
840: PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
841: PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
842: PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT));
844: if (dtype == (PetscInt)PETSC_CHAR) {
845: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR));
846: } else if (dtype == (PetscInt)PETSC_REAL) {
847: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL));
848: } else if (dtype == (PetscInt)PETSC_SCALAR) {
849: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR));
850: } else if (dtype == (PetscInt)PETSC_INT) {
851: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT));
852: } else if (dtype == (PetscInt)PETSC_BOOL) {
853: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL));
854: } else if (dtype == (PetscInt)PETSC_ENUM) {
855: PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM));
856: PetscCall(PetscViewerBinaryReadStringArray(view, &list));
857: /* don't need to save list because it is already registered in the bag */
858: PetscCall(PetscFree(list));
859: }
860: nitem = nitem->next;
861: }
862: PetscFunctionReturn(PETSC_SUCCESS);
863: }
865: /*@
866: PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files,
867: can have values set from the options database
869: Collective
871: Input Parameters:
872: + comm - communicator to share bag
873: - bagsize - size of the C structure holding the values, for example `sizeof(mystruct)`
875: Output Parameter:
876: . bag - the bag of values
878: Level: intermediate
880: Notes:
881: After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout
883: The size of the struct must be small enough to fit in a `PetscInt`; by default
884: `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
885: The warning about casting to a shorter length can be ignored below unless your struct is too large
887: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
888: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
889: `PetscBagSetFromOptions()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
890: @*/
891: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
892: {
893: const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar);
895: PetscFunctionBegin;
896: PetscAssertPointer(bag, 3);
898: PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize));
899: PetscCall(PetscCalloc(totalsize, bag));
900: PetscCall(PetscIntCast(totalsize, &(*bag)->bagsize));
901: (*bag)->bagcomm = comm;
902: (*bag)->bagprefix = NULL;
903: (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar));
904: PetscFunctionReturn(PETSC_SUCCESS);
905: }
907: /*@
908: PetscBagSetName - Sets the name of a bag of values
910: Not Collective
912: Level: intermediate
914: Input Parameters:
915: + bag - the bag of values
916: . name - the name assigned to the bag
917: - help - help message for bag
919: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
920: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
921: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
922: @*/
923: PetscErrorCode PetscBagSetName(PetscBag bag, const char name[], const char help[])
924: {
925: PetscFunctionBegin;
926: PetscAssertPointer(bag, 1);
927: PetscAssertPointer(name, 2);
928: PetscAssertPointer(help, 3);
929: PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1));
930: PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1));
931: PetscFunctionReturn(PETSC_SUCCESS);
932: }
934: /*@
935: PetscBagGetName - Gets the name of a bag of values
937: Not Collective
939: Level: intermediate
941: Input Parameter:
942: . bag - the bag of values
944: Output Parameter:
945: . name - the name assigned to the bag
947: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`,
948: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
949: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
950: @*/
951: PetscErrorCode PetscBagGetName(PetscBag bag, const char *name[])
952: {
953: PetscFunctionBegin;
954: PetscAssertPointer(bag, 1);
955: PetscAssertPointer(name, 2);
956: *name = bag->bagname;
957: PetscFunctionReturn(PETSC_SUCCESS);
958: }
960: /*@
961: PetscBagGetData - Gives back the user - access to memory that
962: can be used for storing user-data-structure
964: Not Collective
966: Input Parameter:
967: . bag - the bag of values
969: Output Parameter:
970: . 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
971: defining the bag
973: Level: intermediate
975: .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`,
976: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
977: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
978: @*/
979: PetscErrorCode PetscBagGetData(PetscBag bag, PetscCtxRt data)
980: {
981: PetscFunctionBegin;
982: PetscAssertPointer(bag, 1);
983: PetscAssertPointer(data, 2);
984: *(void **)data = bag->structlocation;
985: PetscFunctionReturn(PETSC_SUCCESS);
986: }
988: /*@
989: PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
990: `PetscBag` items in the options database.
992: Logically Collective
994: Level: intermediate
996: Input Parameters:
997: + bag - the bag of values
998: - pre - the prefix to prepend all Bag item names with.
1000: Note:
1001: Must be called prior to registering any of the bag items.
1003: .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`,
1004: `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
1005: @*/
1006: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1007: {
1008: PetscFunctionBegin;
1009: PetscAssertPointer(bag, 1);
1010: if (pre) {
1011: PetscAssertPointer(pre, 2);
1012: PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen");
1013: PetscCall(PetscFree(bag->bagprefix));
1014: PetscCall(PetscStrallocpy(pre, &bag->bagprefix));
1015: } else PetscCall(PetscFree(bag->bagprefix));
1016: PetscFunctionReturn(PETSC_SUCCESS);
1017: }
1019: /*@
1020: PetscBagGetNames - Get the names of all entries in the bag
1022: Not Collective
1024: Input Parameter:
1025: . bag - the bag of values
1027: Output Parameter:
1028: . 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.
1030: Level: intermediate
1032: .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()`,
1033: `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
1034: @*/
1035: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1036: {
1037: PetscBagItem nitem = bag->bagitems;
1039: PetscFunctionBegin;
1040: PetscAssertPointer(bag, 1);
1041: PetscAssertPointer(names, 2);
1042: for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
1043: PetscFunctionReturn(PETSC_SUCCESS);
1044: }