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