xref: /petsc/src/sys/classes/bag/bag.c (revision 5b6bfdb9644f185dbf5e5a09b808ec241507e1e7)
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: You must have created and registered all the fields in the bag before loading into it.
774 
775    Notes:
776    Level: beginner
777 
778 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
779            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
780            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
781 
782 @*/
783 PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
784 {
785   PetscErrorCode ierr;
786   PetscBool      isbinary;
787   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
788   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
789   PetscBagItem   nitem;
790   MPI_Comm       comm;
791   PetscMPIInt    flag;
792 
793   PetscFunctionBegin;
794   ierr = PetscObjectGetComm((PetscObject)view,&comm);CHKERRQ(ierr);
795   ierr = MPI_Comm_compare(comm,bag->bagcomm,&flag);CHKERRQ(ierr);
796   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the viewer and bag"); \
797   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
798   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
799 
800   ierr = PetscViewerBinaryRead(view,&classid,1,NULL,PETSC_INT);CHKERRQ(ierr);
801   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
802   ierr = PetscViewerBinaryRead(view,&deprecatedbagsize,1,NULL,PETSC_INT);CHKERRQ(ierr);
803   ierr = PetscViewerBinaryRead(view,&bagcount,1,NULL,PETSC_INT);CHKERRQ(ierr);
804   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);
805   ierr = PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);CHKERRQ(ierr);
806   ierr = PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);CHKERRQ(ierr);
807 
808   nitem = bag->bagitems;
809   for (i=0; i<bagcount; i++) {
810     ierr = PetscViewerBinaryRead(view,&offset,1,NULL,PETSC_INT);CHKERRQ(ierr);
811     /* ignore the offset in the file */
812     ierr = PetscViewerBinaryRead(view,&dtype,1,NULL,PETSC_INT);CHKERRQ(ierr);
813     ierr = PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);CHKERRQ(ierr);
814     ierr = PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);CHKERRQ(ierr);
815     ierr = PetscViewerBinaryRead(view,&msize,1,NULL,PETSC_INT);CHKERRQ(ierr);
816 
817     if (dtype == (PetscInt) PETSC_CHAR) {
818       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_CHAR);CHKERRQ(ierr);
819     } else if (dtype == (PetscInt) PETSC_REAL) {
820       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_REAL);CHKERRQ(ierr);
821     } else if (dtype == (PetscInt) PETSC_SCALAR) {
822       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_SCALAR);CHKERRQ(ierr);
823     } else if (dtype == (PetscInt) PETSC_INT) {
824       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_INT);CHKERRQ(ierr);
825     } else if (dtype == (PetscInt) PETSC_BOOL) {
826       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_BOOL);CHKERRQ(ierr);
827     } else if (dtype == (PetscInt) PETSC_ENUM) {
828       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_ENUM);CHKERRQ(ierr);
829       ierr = PetscViewerBinaryReadStringArray(view,&list);CHKERRQ(ierr);
830       /* don't need to save list because it is already registered in the bag */
831       ierr = PetscFree(list);CHKERRQ(ierr);
832     }
833     nitem = nitem->next;
834   }
835   PetscFunctionReturn(0);
836 }
837 
838 /*@C
839     PetscBagCreate - Create a bag of values
840 
841   Collective on MPI_Comm
842 
843   Level: Intermediate
844 
845   Input Parameters:
846 +  comm - communicator to share bag
847 -  bagsize - size of the C structure holding the values
848 
849   Output Parameter:
850 .   bag - the bag of values
851 
852    Notes:
853       The size of the A struct must be small enough to fit in a PetscInt; by default
854       PetscInt is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
855       The warning about casting to a shorter length can be ignored below unless your A struct is too large
856 
857 .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
858            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
859            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
860 @*/
861 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
862 {
863   PetscErrorCode ierr;
864   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
865 
866   PetscFunctionBegin;
867   ierr = PetscInfo1(NULL,"Creating Bag with total size %d\n",(int)totalsize);CHKERRQ(ierr);
868   ierr = PetscMalloc(totalsize,bag);CHKERRQ(ierr);
869   ierr = PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));CHKERRQ(ierr);
870 
871   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
872   (*bag)->bagcomm        = comm;
873   (*bag)->bagprefix      = NULL;
874   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
875   PetscFunctionReturn(0);
876 }
877 
878 /*@C
879     PetscBagSetName - Sets the name of a bag of values
880 
881   Not Collective
882 
883   Level: Intermediate
884 
885   Input Parameters:
886 +   bag - the bag of values
887 .   name - the name assigned to the bag
888 -   help - help message for bag
889 
890 .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
891            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
892            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
893 @*/
894 
895 PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
896 {
897   PetscErrorCode ierr;
898 
899   PetscFunctionBegin;
900   ierr = PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
901   ierr = PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);CHKERRQ(ierr);
902   PetscFunctionReturn(0);
903 }
904 
905 
906 /*@C
907     PetscBagGetName - Gets the name of a bag of values
908 
909   Not Collective
910 
911   Level: Intermediate
912 
913   Input Parameter:
914 .   bag - the bag of values
915 
916   Output Parameter:
917 .   name - the name assigned to the bag
918 
919 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
920            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
921            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
922 @*/
923 PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
924 {
925   PetscFunctionBegin;
926   *name = bag->bagname;
927   PetscFunctionReturn(0);
928 }
929 
930 /*@C
931     PetscBagGetData - Gives back the user - access to memory that
932     should be used for storing user-data-structure
933 
934   Not Collective
935 
936   Level: Intermediate
937 
938   Input Parameter:
939 .   bag - the bag of values
940 
941   Output Parameter:
942 .   data - pointer to memory that will have user-data-structure
943 
944 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
945            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
946            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
947 @*/
948 PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
949 {
950   PetscFunctionBegin;
951   *data = bag->structlocation;
952   PetscFunctionReturn(0);
953 }
954 
955 /*@C
956   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
957   PetscBag items in the options database.
958 
959   Logically collective on Bag.
960 
961   Level: Intermediate
962 
963   Input Parameters:
964 +   bag - the bag of values
965 -   prefix - the prefix to prepend all Bag item names with.
966 
967   NOTES: Must be called prior to registering any of the bag items.
968 
969 .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
970            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
971 @*/
972 
973 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
974 {
975   PetscErrorCode ierr;
976 
977   PetscFunctionBegin;
978   if (!pre) {
979     ierr = PetscFree(bag->bagprefix);CHKERRQ(ierr);
980   } else {
981     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
982     ierr = PetscFree(bag->bagprefix);CHKERRQ(ierr);
983     ierr = PetscStrallocpy(pre,&(bag->bagprefix));CHKERRQ(ierr);
984   }
985   PetscFunctionReturn(0);
986 }
987 
988 /*@C
989   PetscBagGetNames - Get the names of all entries in the bag
990 
991   Not collective
992 
993   Input Parameters:
994 + bag   - the bag of values
995 - names - array of the correct size to hold names
996 
997   Output Parameter:
998 . names - array of char pointers for names
999 
1000   Level: intermediate
1001 
1002 .seealso: PetscBag, PetscBagGetName(), PetscBagSetName(), PetscBagCreate(), PetscBagGetData()
1003           PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
1004 @*/
1005 PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1006 {
1007   PetscBagItem nitem = bag->bagitems;
1008   PetscInt     n;
1009 
1010   PetscFunctionBegin;
1011   for (n = 0; nitem; ++n, nitem = nitem->next) {names[n] = nitem->name;}
1012   PetscFunctionReturn(0);
1013 }
1014