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