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