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