xref: /petsc/src/sys/classes/bag/bag.c (revision fccf883b8d575dff35c78ade578d5b4ecfb79779)
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     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);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     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);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     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);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     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);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     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);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   /* ierr = PetscMemzero(addr,msize*sizeof(PetscInt));CHKERRQ(ierr);*/
311   nname[0] = '-';
312   nname[1] = 0;
313   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
314   ierr     = PetscOptionsHasName(NULL,NULL,"-help",&printhelp);CHKERRQ(ierr);
315   if (printhelp) {
316     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix?bag->bagprefix:"",name);CHKERRQ(ierr);
317     for (i=0; i<msize; i++) {
318       ierr = (*PetscHelpPrintf)(bag->bagcomm,"%D ",*((PetscInt*)addr)+i);CHKERRQ(ierr);
319     }
320     ierr = (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);CHKERRQ(ierr);
321   }
322   ierr = PetscOptionsGetBoolArray(NULL,bag->bagprefix,nname,(PetscBool*)addr,&tmp,NULL);CHKERRQ(ierr);
323 
324   ierr = PetscNew(&item);CHKERRQ(ierr);
325   item->dtype  = PETSC_BOOL;
326   item->offset = ((char*)addr) - ((char*)bag);
327   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);
328   item->next   = 0;
329   item->msize  = msize;
330   ierr = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
331   PetscFunctionReturn(0);
332 }
333 
334 /*@C
335    PetscBagRegisterString - add a string value to the bag
336 
337    Logically Collective on PetscBag
338 
339    Input Parameter:
340 +  bag - the bag of values
341 .  addr - location of start of string in struct
342 .  msize - length of the string space in the struct
343 .  mdefault - the initial value
344 .  name - name of the string
345 -  help - longer string with more information about the value
346 
347    Level: beginner
348 
349    Note: The struct should have the field char mystring[msize]; not char *mystring
350 
351 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
352            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
353            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
354 
355 @*/
356 PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault,const char* name,const char* help)
357 {
358   PetscErrorCode ierr;
359   PetscBagItem   item;
360   char           nname[PETSC_BAG_NAME_LENGTH+1];
361   PetscBool      printhelp;
362 
363   PetscFunctionBegin;
364   nname[0] = '-';
365   nname[1] = 0;
366   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
367   ierr     = PetscOptionsHasName(NULL,NULL,"-help",&printhelp);CHKERRQ(ierr);
368   if (printhelp) {
369     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);CHKERRQ(ierr);
370   }
371 
372   ierr         = PetscNew(&item);CHKERRQ(ierr);
373   item->dtype  = PETSC_CHAR;
374   item->offset = ((char*)addr) - ((char*)bag);
375   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);
376   item->next  = 0;
377   item->msize = msize;
378   if (mdefault != (char*)addr) {
379     ierr = PetscStrncpy((char*)addr,mdefault,msize-1);CHKERRQ(ierr);
380   }
381   ierr = PetscOptionsGetString(NULL,bag->bagprefix,nname,(char*)addr,msize,NULL);CHKERRQ(ierr);
382   ierr = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
383   PetscFunctionReturn(0);
384 }
385 
386 /*@C
387    PetscBagRegisterReal - add a real value to the bag
388 
389    Logically Collective on PetscBag
390 
391    Input Parameter:
392 +  bag - the bag of values
393 .  addr - location of double in struct
394 .  mdefault - the initial value
395 .  name - name of the variable
396 -  help - longer string with more information about the value
397 
398    Level: beginner
399 
400 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
401            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
402            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
403 
404 @*/
405 PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char *name, const char *help)
406 {
407   PetscErrorCode ierr;
408   PetscBagItem   item;
409   char           nname[PETSC_BAG_NAME_LENGTH+1];
410   PetscBool      printhelp;
411 
412   PetscFunctionBegin;
413   nname[0] = '-';
414   nname[1] = 0;
415   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
416   ierr     = PetscOptionsHasName(NULL,NULL,"-help",&printhelp);CHKERRQ(ierr);
417   if (printhelp) {
418     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)mdefault,help);CHKERRQ(ierr);
419   }
420   ierr = PetscOptionsGetReal(NULL,bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
421 
422   ierr         = PetscNew(&item);CHKERRQ(ierr);
423   item->dtype  = PETSC_REAL;
424   item->offset = ((char*)addr) - ((char*)bag);
425   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);
426   item->next        = 0;
427   item->msize       = 1;
428   *(PetscReal*)addr = mdefault;
429   ierr              = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
430   PetscFunctionReturn(0);
431 }
432 
433 /*@C
434    PetscBagRegisterScalar - add a real or complex number value to the bag
435 
436    Logically Collective on PetscBag
437 
438    Input Parameter:
439 +  bag - the bag of values
440 .  addr - location of scalar in struct
441 .  mdefault - the initial value
442 .  name - name of the variable
443 -  help - longer string with more information about the value
444 
445 
446    Level: beginner
447 
448 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
449            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
450            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
451 
452 @*/
453 PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
454 {
455   PetscErrorCode ierr;
456   PetscBagItem   item;
457   char           nname[PETSC_BAG_NAME_LENGTH+1];
458   PetscBool      printhelp;
459 
460   PetscFunctionBegin;
461   nname[0] = '-';
462   nname[1] = 0;
463   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
464   ierr     = PetscOptionsHasName(NULL,NULL,"-help",&printhelp);CHKERRQ(ierr);
465   if (printhelp) {
466     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g + %gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)PetscRealPart(mdefault),(double)PetscImaginaryPart(mdefault),help);CHKERRQ(ierr);
467   }
468   ierr = PetscOptionsGetScalar(NULL,bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
469 
470   ierr         = PetscNew(&item);CHKERRQ(ierr);
471   item->dtype  = PETSC_SCALAR;
472   item->offset = ((char*)addr) - ((char*)bag);
473   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);
474   item->next          = 0;
475   item->msize         = 1;
476   *(PetscScalar*)addr = mdefault;
477   ierr                = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
478   PetscFunctionReturn(0);
479 }
480 
481 /*@C
482    PetscBagRegisterBool - add a logical value to the bag
483 
484    Logically Collective on PetscBag
485 
486    Input Parameter:
487 +  bag - the bag of values
488 .  addr - location of logical in struct
489 .  mdefault - the initial value
490 .  name - name of the variable
491 -  help - longer string with more information about the value
492 
493 
494    Level: beginner
495 
496 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
497            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
498            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
499 
500 @*/
501 PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
502 {
503   PetscErrorCode ierr;
504   PetscBagItem   item;
505   char           nname[PETSC_BAG_NAME_LENGTH+1];
506   PetscBool      printhelp;
507 
508   PetscFunctionBegin;
509   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
510   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);
511   nname[0] = '-';
512   nname[1] = 0;
513   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
514   ierr     = PetscOptionsHasName(NULL,NULL,"-help",&printhelp);CHKERRQ(ierr);
515   if (printhelp) {
516     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);CHKERRQ(ierr);
517   }
518   ierr = PetscOptionsGetBool(NULL,bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
519 
520   ierr         = PetscNew(&item);CHKERRQ(ierr);
521   item->dtype  = PETSC_BOOL;
522   item->offset = ((char*)addr) - ((char*)bag);
523   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);
524   item->next        = 0;
525   item->msize       = 1;
526   *(PetscBool*)addr = mdefault;
527   ierr              = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
528   PetscFunctionReturn(0);
529 }
530 
531 /*@C
532    PetscBagDestroy - Destroys a bag values
533 
534    Collective on PetscBag
535 
536    Input Parameter:
537 .  bag - the bag of values
538 
539    Level: beginner
540 
541 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
542            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
543            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
544 
545 @*/
546 PetscErrorCode  PetscBagDestroy(PetscBag *bag)
547 {
548   PetscErrorCode ierr;
549   PetscBagItem   nitem = (*bag)->bagitems,item;
550 
551   PetscFunctionBegin;
552   while (nitem) {
553     item = nitem->next;
554     if (nitem->list) {
555       ierr = PetscStrArrayDestroy(&nitem->list);CHKERRQ(ierr);
556     }
557     ierr  = PetscFree(nitem);CHKERRQ(ierr);
558     nitem = item;
559   }
560   if ((*bag)->bagprefix) { ierr = PetscFree((*bag)->bagprefix);CHKERRQ(ierr); }
561   ierr = PetscFree(*bag);CHKERRQ(ierr);
562   PetscFunctionReturn(0);
563 }
564 
565 /*@
566    PetscBagSetFromOptions - Allows setting options from a bag
567 
568    Collective on PetscBag
569 
570    Input Parameter:
571 .  bag - the bag of values
572 
573    Level: beginner
574 
575 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
576            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
577            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()
578 
579 @*/
580 PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
581 {
582   PetscErrorCode ierr;
583   PetscBagItem   nitem = bag->bagitems;
584   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
585   PetscInt       n;
586 
587   PetscFunctionBegin;
588   ierr = PetscStrcpy(helpname,bag->bagname);CHKERRQ(ierr);
589   ierr = PetscStrcat(helpname," ");CHKERRQ(ierr);
590   ierr = PetscStrcat(helpname,bag->baghelp);CHKERRQ(ierr);
591   ierr = PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,0);CHKERRQ(ierr);
592   while (nitem) {
593     name[0] = '-';
594     name[1] = 0;
595     ierr    = PetscStrcat(name,nitem->name);CHKERRQ(ierr);
596     if (nitem->dtype == PETSC_CHAR) {   /* special handling for fortran required? [due to space padding vs null termination] */
597       char *value = (char*)(((char*)bag) + nitem->offset);
598       ierr = PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,NULL);CHKERRQ(ierr);
599     } else if (nitem->dtype == PETSC_REAL) {
600       PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
601       if (nitem->msize == 1) {
602         ierr = PetscOptionsReal(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
603       } else {
604         n    = nitem->msize;
605         ierr = PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);CHKERRQ(ierr);
606       }
607     } else if (nitem->dtype == PETSC_SCALAR) {
608       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
609       ierr = PetscOptionsScalar(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
610     } else if (nitem->dtype == PETSC_INT) {
611       PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
612       if (nitem->msize == 1) {
613         ierr = PetscOptionsInt(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
614       } else {
615         n    = nitem->msize;
616         ierr = PetscOptionsIntArray(name,nitem->help,"",value,&n,NULL);CHKERRQ(ierr);
617       }
618     } else if (nitem->dtype == PETSC_ENUM) {
619       PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
620       PetscInt  i      = 0;
621       while (nitem->list[i++]) ;
622       ierr = PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,NULL);CHKERRQ(ierr);
623     } else if (nitem->dtype == PETSC_BOOL) {
624       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
625       if (nitem->msize == 1) {
626         ierr = PetscOptionsBool(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
627       } else {
628         n = nitem->msize;
629         ierr = PetscOptionsBoolArray(name,nitem->help,"",value,&n,NULL);CHKERRQ(ierr);
630       }
631     }
632     nitem = nitem->next;
633   }
634   PetscOptionsEnd();
635   PetscFunctionReturn(0);
636 }
637 
638 /*@C
639    PetscBagView - Views a bag of values as either ASCII text or a binary file
640 
641    Collective on PetscBag
642 
643    Input Parameter:
644 +  bag - the bag of values
645 -  viewer - location to view the values
646 
647    Level: beginner
648 
649    Warning: Currently PETSc bags saved in a binary file can only be read back
650      in on a machine of the same architecture. Let us know when this is a problem
651      and we'll fix it.
652 
653 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
654            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
655            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()
656 
657 @*/
658 PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
659 {
660   PetscBool      isascii,isbinary;
661   PetscErrorCode ierr;
662   PetscBagItem   nitem = bag->bagitems;
663 
664   PetscFunctionBegin;
665   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
666   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
667   if (isascii) {
668     if (bag->bagprefix) {
669       ierr = PetscViewerASCIIPrintf(view,"PetscBag Object:  %s (%s) %s\n",bag->bagname,bag->bagprefix,bag->baghelp);CHKERRQ(ierr);
670     } else {
671       ierr = PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);CHKERRQ(ierr);
672     }
673     while (nitem) {
674       if (nitem->dtype == PETSC_CHAR) {
675         char *value = (char*)(((char*)bag) + nitem->offset);
676         char tmp    = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
677         value[nitem->msize-1] =0;
678         ierr = PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);CHKERRQ(ierr);
679         value[nitem->msize-1] = tmp;
680       } else if (nitem->dtype == PETSC_REAL) {
681         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
682         PetscInt  i;
683         ierr = PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);CHKERRQ(ierr);
684         for (i=0; i<nitem->msize; i++) {
685           ierr = PetscViewerASCIIPrintf(view,"%g ",(double)value[i]);CHKERRQ(ierr);
686         }
687         ierr = PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);CHKERRQ(ierr);
688       } else if (nitem->dtype == PETSC_SCALAR) {
689         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
690 #if defined(PETSC_USE_COMPLEX)
691         if ((double)PetscImaginaryPart(value)) {
692           ierr = PetscViewerASCIIPrintf(view,"  %s = %g + %gi; %s\n",nitem->name,(double)PetscRealPart(value),(double)PetscImaginaryPart(value),nitem->help);CHKERRQ(ierr);
693         } else {
694           ierr = PetscViewerASCIIPrintf(view,"  %s = %g; %s\n",nitem->name,(double)PetscRealPart(value),nitem->help);CHKERRQ(ierr);
695         }
696 #else
697         ierr = PetscViewerASCIIPrintf(view,"  %s = %g; %s\n",nitem->name,(double)value,nitem->help);CHKERRQ(ierr);
698 #endif
699       } else if (nitem->dtype == PETSC_INT) {
700         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
701         ierr = PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);CHKERRQ(ierr);
702         for (i=0; i<nitem->msize; i++) {
703           ierr = PetscViewerASCIIPrintf(view,"%D ",value[i]);CHKERRQ(ierr);
704         }
705         ierr = PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);CHKERRQ(ierr);
706       } else if (nitem->dtype == PETSC_BOOL) {
707         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
708         PetscInt  i;
709          /* some Fortran compilers use -1 as boolean */
710         ierr = PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);CHKERRQ(ierr);
711         for (i=0; i<nitem->msize; i++) {
712           if (((int) value[i]) == -1) value[i] = PETSC_TRUE;
713           /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
714           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);
715           ierr = PetscViewerASCIIPrintf(view," %s",PetscBools[value[i]]);CHKERRQ(ierr);
716         }
717         ierr = PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);CHKERRQ(ierr);
718       } else if (nitem->dtype == PETSC_ENUM) {
719         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
720         PetscInt  i     = 0;
721         while (nitem->list[i++]) ;
722         ierr = PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);CHKERRQ(ierr);
723       }
724       nitem = nitem->next;
725     }
726   } else if (isbinary) {
727     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
728     PetscInt          deprecatedbagsize = 0;
729     PetscViewerFormat format;
730     ierr = PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
731     ierr = PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
732     ierr = PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
733     ierr = PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
734     ierr = PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
735     while (nitem) {
736       ierr  = PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
737       dtype = (PetscInt)nitem->dtype;
738       ierr  = PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
739       ierr  = PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
740       ierr  = PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
741       ierr  = PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
742       /* some Fortran compilers use -1 as boolean */
743       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;
744 
745       ierr = PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);CHKERRQ(ierr);
746       if (dtype == PETSC_ENUM) {
747         ierr = PetscViewerBinaryWriteStringArray(view,(const char* const*)nitem->list);CHKERRQ(ierr);
748       }
749       nitem = nitem->next;
750     }
751     ierr = PetscViewerGetFormat(view,&format);CHKERRQ(ierr);
752     if (format == PETSC_VIEWER_BINARY_MATLAB) {
753       MPI_Comm comm;
754       FILE     *info;
755       ierr = PetscObjectGetComm((PetscObject)view,&comm);CHKERRQ(ierr);
756       ierr = PetscViewerBinaryGetInfoPointer(view,&info);CHKERRQ(ierr);
757       ierr = PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");CHKERRQ(ierr);
758       ierr = PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);CHKERRQ(ierr);
759       ierr = PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");CHKERRQ(ierr);
760     }
761   }
762   PetscFunctionReturn(0);
763 }
764 
765 /*@C
766    PetscBagLoad - Loads a bag of values from a binary file
767 
768    Collective on PetscViewer
769 
770    Input Parameter:
771 +  viewer - file to load values from
772 -  bag - the bag of values
773 
774    Notes: 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