xref: /petsc/src/sys/classes/bag/bag.c (revision 6ac5842e34eedc6428162d8d42bedaaf46eae34c)
1 
2 #include <../src/sys/classes/bag/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(struct _n_PetscBagItem,&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(struct _n_PetscBagItem,&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 ",*((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(struct _n_PetscBagItem,&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            PetscBagRegisterInt(), 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(struct _n_PetscBagItem,&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__ "PetscBagRegisterString"
244 /*@C
245    PetscBagRegisterString - add a string value to the bag
246 
247    Logically Collective on PetscBag
248 
249    Input Parameter:
250 +  bag - the bag of values
251 .  addr - location of start of string in struct
252 .  msize - length of the string space in the struct
253 .  mdefault - the initial value
254 .  name - name of the string
255 -  help - longer string with more information about the value
256 
257    Level: beginner
258 
259    Note: The struct should have the field char mystring[msize]; not char *mystring
260 
261 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
262            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
263            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
264 
265 @*/
266 PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault,const char* name,const char* help)
267 {
268   PetscErrorCode ierr;
269   PetscBagItem   item;
270   char           nname[PETSC_BAG_NAME_LENGTH+1];
271   PetscBool      printhelp;
272 
273   PetscFunctionBegin;
274   nname[0] = '-';
275   nname[1] = 0;
276   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
277   ierr     = PetscOptionsHasName(NULL,"-help",&printhelp);CHKERRQ(ierr);
278   if (printhelp) {
279     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);CHKERRQ(ierr);
280   }
281 
282   ierr         = PetscNew(struct _n_PetscBagItem,&item);CHKERRQ(ierr);
283   item->dtype  = PETSC_CHAR;
284   item->offset = ((char*)addr) - ((char*)bag);
285   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);
286   item->next  = 0;
287   item->msize = msize;
288   if (mdefault != (char*)addr) {
289     ierr = PetscStrncpy((char*)addr,mdefault,msize-1);CHKERRQ(ierr);
290   }
291   ierr = PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,NULL);CHKERRQ(ierr);
292   ierr = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
293   PetscFunctionReturn(0);
294 }
295 
296 #undef __FUNCT__
297 #define __FUNCT__ "PetscBagRegisterReal"
298 /*@C
299    PetscBagRegisterReal - add a real value to the bag
300 
301    Logically Collective on PetscBag
302 
303    Input Parameter:
304 +  bag - the bag of values
305 .  addr - location of double in struct
306 .  mdefault - the initial value
307 .  name - name of the variable
308 -  help - longer string with more information about the value
309 
310    Level: beginner
311 
312 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
313            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
314            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
315 
316 @*/
317 PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char *name, const char *help)
318 {
319   PetscErrorCode ierr;
320   PetscBagItem   item;
321   char           nname[PETSC_BAG_NAME_LENGTH+1];
322   PetscBool      printhelp;
323 
324   PetscFunctionBegin;
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 <%G>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);CHKERRQ(ierr);
331   }
332   ierr = PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
333 
334   ierr         = PetscNew(struct _n_PetscBagItem,&item);CHKERRQ(ierr);
335   item->dtype  = PETSC_REAL;
336   item->offset = ((char*)addr) - ((char*)bag);
337   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);
338   item->next        = 0;
339   item->msize       = 1;
340   *(PetscReal*)addr = mdefault;
341   ierr              = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
342   PetscFunctionReturn(0);
343 }
344 
345 #undef __FUNCT__
346 #define __FUNCT__ "PetscBagRegisterScalar"
347 /*@C
348    PetscBagRegisterScalar - add a real or complex number value to the bag
349 
350    Logically Collective on PetscBag
351 
352    Input Parameter:
353 +  bag - the bag of values
354 .  addr - location of scalar in struct
355 .  mdefault - the initial value
356 .  name - name of the variable
357 -  help - longer string with more information about the value
358 
359 
360    Level: beginner
361 
362 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
363            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
364            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
365 
366 @*/
367 PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
368 {
369   PetscErrorCode ierr;
370   PetscBagItem   item;
371   char           nname[PETSC_BAG_NAME_LENGTH+1];
372   PetscBool      printhelp;
373 
374   PetscFunctionBegin;
375   nname[0] = '-';
376   nname[1] = 0;
377   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
378   ierr     = PetscOptionsHasName(NULL,"-help",&printhelp);CHKERRQ(ierr);
379   if (printhelp) {
380     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G + %Gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);CHKERRQ(ierr);
381   }
382   ierr = PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
383 
384   ierr         = PetscNew(struct _n_PetscBagItem,&item);CHKERRQ(ierr);
385   item->dtype  = PETSC_SCALAR;
386   item->offset = ((char*)addr) - ((char*)bag);
387   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);
388   item->next          = 0;
389   item->msize         = 1;
390   *(PetscScalar*)addr = mdefault;
391   ierr                = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
392   PetscFunctionReturn(0);
393 }
394 
395 #undef __FUNCT__
396 #define __FUNCT__ "PetscBagRegisterBool"
397 /*@C
398    PetscBagRegisterBool - add a logical value to the bag
399 
400    Logically Collective on PetscBag
401 
402    Input Parameter:
403 +  bag - the bag of values
404 .  addr - location of logical in struct
405 .  mdefault - the initial value
406 .  name - name of the variable
407 -  help - longer string with more information about the value
408 
409 
410    Level: beginner
411 
412 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
413            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
414            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
415 
416 @*/
417 PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
418 {
419   PetscErrorCode ierr;
420   PetscBagItem   item;
421   char           nname[PETSC_BAG_NAME_LENGTH+1];
422   PetscBool      printhelp;
423 
424   PetscFunctionBegin;
425   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
426   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);
427   nname[0] = '-';
428   nname[1] = 0;
429   ierr     = PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
430   ierr     = PetscOptionsHasName(NULL,"-help",&printhelp);CHKERRQ(ierr);
431   if (printhelp) {
432     ierr = (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);CHKERRQ(ierr);
433   }
434   ierr = PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,NULL);CHKERRQ(ierr);
435 
436   ierr         = PetscNew(struct _n_PetscBagItem,&item);CHKERRQ(ierr);
437   item->dtype  = PETSC_BOOL;
438   item->offset = ((char*)addr) - ((char*)bag);
439   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);
440   item->next        = 0;
441   item->msize       = 1;
442   *(PetscBool*)addr = mdefault;
443   ierr              = PetscBagRegister_Private(bag,item,name,help);CHKERRQ(ierr);
444   PetscFunctionReturn(0);
445 }
446 
447 #undef __FUNCT__
448 #define __FUNCT__ "PetscBagDestroy"
449 /*@C
450    PetscBagDestroy - Destroys a bag values
451 
452    Collective on PetscBag
453 
454    Input Parameter:
455 .  bag - the bag of values
456 
457    Level: beginner
458 
459 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
460            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
461            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
462 
463 @*/
464 PetscErrorCode  PetscBagDestroy(PetscBag *bag)
465 {
466   PetscErrorCode ierr;
467   PetscBagItem   nitem = (*bag)->bagitems,item;
468 
469   PetscFunctionBegin;
470   while (nitem) {
471     item = nitem->next;
472     if (nitem->list) {
473       ierr = PetscStrArrayDestroy(&nitem->list);CHKERRQ(ierr);
474     }
475     ierr  = PetscFree(nitem);CHKERRQ(ierr);
476     nitem = item;
477   }
478   if ((*bag)->bagprefix) { ierr = PetscFree((*bag)->bagprefix);CHKERRQ(ierr); }
479   ierr = PetscFree(*bag);CHKERRQ(ierr);
480   PetscFunctionReturn(0);
481 }
482 
483 #undef __FUNCT__
484 #define __FUNCT__ "PetscBagSetFromOptions"
485 /*@
486    PetscBagSetFromOptions - Allows setting options from a bag
487 
488    Collective on PetscBag
489 
490    Input Parameter:
491 .  bag - the bag of values
492 
493    Level: beginner
494 
495 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
496            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
497            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()
498 
499 @*/
500 PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
501 {
502   PetscErrorCode ierr;
503   PetscBagItem   nitem = bag->bagitems;
504   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
505   PetscInt       n;
506 
507   PetscFunctionBegin;
508   ierr = PetscStrcpy(helpname,bag->bagname);CHKERRQ(ierr);
509   ierr = PetscStrcat(helpname," ");CHKERRQ(ierr);
510   ierr = PetscStrcat(helpname,bag->baghelp);CHKERRQ(ierr);
511   ierr = PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,0);
512   while (nitem) {
513     name[0] = '-';
514     name[1] = 0;
515     ierr    = PetscStrcat(name,nitem->name);CHKERRQ(ierr);
516     if (nitem->dtype == PETSC_CHAR) {   /* special handling for fortran required? [due to space padding vs null termination] */
517       char *value = (char*)(((char*)bag) + nitem->offset);
518       ierr = PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,NULL);CHKERRQ(ierr);
519     } else if (nitem->dtype == PETSC_REAL) {
520       PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
521       if (nitem->msize == 1) {
522         ierr = PetscOptionsReal(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
523       } else {
524         n    = nitem->msize;
525         ierr = PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);CHKERRQ(ierr);
526       }
527     } else if (nitem->dtype == PETSC_SCALAR) {
528       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
529       ierr = PetscOptionsScalar(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
530     } else if (nitem->dtype == PETSC_INT) {
531       PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
532       if (nitem->msize == 1) {
533         ierr = PetscOptionsInt(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
534       } else {
535         n    = nitem->msize;
536         ierr = PetscOptionsIntArray(name,nitem->help,"",value,&n,NULL);CHKERRQ(ierr);
537       }
538     } else if (nitem->dtype == PETSC_ENUM) {
539       PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
540       PetscInt  i      = 0;
541       while (nitem->list[i++]) ;
542       ierr = PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,NULL);CHKERRQ(ierr);
543     } else if (nitem->dtype == PETSC_BOOL) {
544       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
545       ierr = PetscOptionsBool(name,nitem->help,"",*value,value,NULL);CHKERRQ(ierr);
546     }
547     nitem = nitem->next;
548   }
549   PetscOptionsEnd();
550   PetscFunctionReturn(0);
551 }
552 
553 #undef __FUNCT__
554 #define __FUNCT__ "PetscBagView"
555 /*@C
556    PetscBagView - Views a bag of values as either ASCII text or a binary file
557 
558    Collective on PetscBag
559 
560    Input Parameter:
561 +  bag - the bag of values
562 -  viewer - location to view the values
563 
564    Level: beginner
565 
566    Warning: Currently PETSc bags saved in a binary file can only be read back
567      in on a machine of the same architecture. Let us know when this is a problem
568      and we'll fix it.
569 
570 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
571            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
572            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()
573 
574 @*/
575 PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
576 {
577   PetscBool      isascii,isbinary;
578   PetscErrorCode ierr;
579   PetscBagItem   nitem = bag->bagitems;
580 
581   PetscFunctionBegin;
582   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
583   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
584   if (isascii) {
585     ierr = PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);CHKERRQ(ierr);
586     while (nitem) {
587       if (nitem->dtype == PETSC_CHAR) {
588         char *value = (char*)(((char*)bag) + nitem->offset);
589         char tmp    = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
590         value[nitem->msize-1] =0;
591         ierr = PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);CHKERRQ(ierr);
592         value[nitem->msize-1] = tmp;
593       } else if (nitem->dtype == PETSC_REAL) {
594         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
595         PetscInt  i;
596         ierr = PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);CHKERRQ(ierr);
597         for (i=0; i<nitem->msize; i++) {
598           ierr = PetscViewerASCIIPrintf(view,"%G ",value[i]);CHKERRQ(ierr);
599         }
600         ierr = PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);CHKERRQ(ierr);
601       } else if (nitem->dtype == PETSC_SCALAR) {
602         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
603 #if defined(PETSC_USE_COMPLEX)
604         ierr = PetscViewerASCIIPrintf(view,"  %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);CHKERRQ(ierr);
605 #else
606         ierr = PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);CHKERRQ(ierr);
607 #endif
608       } else if (nitem->dtype == PETSC_INT) {
609         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
610         ierr = PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);CHKERRQ(ierr);
611         for (i=0; i<nitem->msize; i++) {
612           ierr = PetscViewerASCIIPrintf(view,"%D ",value[i]);CHKERRQ(ierr);
613         }
614         ierr = PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);CHKERRQ(ierr);
615       } else if (nitem->dtype == PETSC_BOOL) {
616         PetscBool value = *(PetscBool*)(((char*)bag) + nitem->offset);
617         /* some Fortran compilers use -1 as boolean */
618         if (((int) value) == -1) value = PETSC_TRUE;
619         /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
620         if (value != PETSC_FALSE && value != PETSC_TRUE) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Boolean value for %s %s is corrupt; integer value %d",nitem->name,nitem->help,value);
621         ierr = PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,PetscBools[value],nitem->help);CHKERRQ(ierr);
622       } else if (nitem->dtype == PETSC_ENUM) {
623         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
624         PetscInt  i     = 0;
625         while (nitem->list[i++]) ;
626         ierr = PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);CHKERRQ(ierr);
627       }
628       nitem = nitem->next;
629     }
630   } else if (isbinary) {
631     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
632     PetscInt          deprecatedbagsize = 0;
633     PetscViewerFormat format;
634     ierr = PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr);
635     ierr = PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
636     ierr = PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
637     ierr = PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
638     ierr = PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
639     while (nitem) {
640       ierr  = PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
641       dtype = (PetscInt)nitem->dtype;
642       ierr  = PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
643       ierr  = PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
644       ierr  = PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);CHKERRQ(ierr);
645       ierr  = PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr);
646       /* some Fortran compilers use -1 as boolean */
647       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;
648 
649       ierr = PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);CHKERRQ(ierr);
650       if (dtype == PETSC_ENUM) {
651         ierr = PetscViewerBinaryWriteStringArray(view,(char**)nitem->list);CHKERRQ(ierr);
652       }
653       nitem = nitem->next;
654     }
655     ierr = PetscViewerGetFormat(view,&format);CHKERRQ(ierr);
656     if (format == PETSC_VIEWER_BINARY_MATLAB) {
657       MPI_Comm comm;
658       FILE     *info;
659       ierr = PetscObjectGetComm((PetscObject)view,&comm);CHKERRQ(ierr);
660       ierr = PetscViewerBinaryGetInfoPointer(view,&info);CHKERRQ(ierr);
661       ierr = PetscFPrintf(comm,info,"%%--- begin code written by PetscViewerBinary for MATLAB format ---%\n");CHKERRQ(ierr);
662       ierr = PetscFPrintf(comm,info,"%%$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);CHKERRQ(ierr);
663       ierr = PetscFPrintf(comm,info,"%%--- end code written by PetscViewerBinary for MATLAB format ---%\n\n");CHKERRQ(ierr);
664     }
665   }
666   PetscFunctionReturn(0);
667 }
668 
669 #undef __FUNCT__
670 #define __FUNCT__ "PetscBagLoad"
671 /*@C
672    PetscBagLoad - Loads a bag of values from a binary file
673 
674    Collective on PetscViewer
675 
676    Input Parameter:
677 +  viewer - file to load values from
678 -  bag - the bag of values
679 
680    Notes: You must have created and registered all the fields in the bag before loading into it.
681 
682    Notes:
683    Level: beginner
684 
685 .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
686            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
687            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()
688 
689 @*/
690 PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
691 {
692   PetscErrorCode ierr;
693   PetscBool      isbinary;
694   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
695   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
696   PetscBagItem   nitem;
697   MPI_Comm       comm;
698   PetscMPIInt    flag;
699 
700   PetscFunctionBegin;
701   ierr = PetscObjectGetComm((PetscObject)view,&comm);CHKERRQ(ierr);
702   ierr = MPI_Comm_compare(comm,bag->bagcomm,&flag);CHKERRQ(ierr);
703   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the viewer and bag"); \
704   ierr = PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr);
705   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
706 
707   ierr = PetscViewerBinaryRead(view,&classid,1,PETSC_INT);CHKERRQ(ierr);
708   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
709   ierr = PetscViewerBinaryRead(view,&deprecatedbagsize,1,PETSC_INT);CHKERRQ(ierr);
710   ierr = PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);CHKERRQ(ierr);
711   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);
712   ierr = PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);CHKERRQ(ierr);
713   ierr = PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);CHKERRQ(ierr);
714 
715   nitem = bag->bagitems;
716   for (i=0; i<bagcount; i++) {
717     ierr = PetscViewerBinaryRead(view,&offset,1,PETSC_INT);CHKERRQ(ierr);
718     /* ignore the offset in the file */
719     ierr = PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);CHKERRQ(ierr);
720     ierr = PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);CHKERRQ(ierr);
721     ierr = PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);CHKERRQ(ierr);
722     ierr = PetscViewerBinaryRead(view,&msize,1,PETSC_INT);CHKERRQ(ierr);
723 
724     if (dtype == (PetscInt) PETSC_CHAR) {
725       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);CHKERRQ(ierr);
726     } else if (dtype == (PetscInt) PETSC_REAL) {
727       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_REAL);CHKERRQ(ierr);
728     } else if (dtype == (PetscInt) PETSC_SCALAR) {
729       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);CHKERRQ(ierr);
730     } else if (dtype == (PetscInt) PETSC_INT) {
731       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_INT);CHKERRQ(ierr);
732     } else if (dtype == (PetscInt) PETSC_BOOL) {
733       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_BOOL);CHKERRQ(ierr);
734     } else if (dtype == (PetscInt) PETSC_ENUM) {
735       ierr = PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);CHKERRQ(ierr);
736       ierr = PetscViewerBinaryReadStringArray(view,&list);CHKERRQ(ierr);
737       /* don't need to save list because it is already registered in the bag */
738       ierr = PetscFree(list);CHKERRQ(ierr);
739     }
740     nitem = nitem->next;
741   }
742   PetscFunctionReturn(0);
743 }
744 
745 #undef __FUNCT__
746 #define __FUNCT__ "PetscBagCreate"
747 /*@
748     PetscBagCreate - Create a bag of values
749 
750   Collective on MPI_Comm
751 
752   Level: Intermediate
753 
754   Input Parameters:
755 +  comm - communicator to share bag
756 -  bagsize - size of the C structure holding the values
757 
758   Output Parameter:
759 .   bag - the bag of values
760 
761    Notes:
762       The size of the A struct must be small enough to fit in a PetscInt; by default
763       PetscInt is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
764       The warning about casting to a shorter length can be ignored below unless your A struct is too large
765 
766 .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
767            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
768            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
769 @*/
770 PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
771 {
772   PetscErrorCode ierr;
773   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
774 
775   PetscFunctionBegin;
776   ierr = PetscInfo1(NULL,"Creating Bag with total size %d\n",(int)totalsize);CHKERRQ(ierr);
777   ierr = PetscMalloc(totalsize,bag);CHKERRQ(ierr);
778   ierr = PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));CHKERRQ(ierr);
779 
780   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
781   (*bag)->bagcomm        = comm;
782   (*bag)->bagprefix      = NULL;
783   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
784   PetscFunctionReturn(0);
785 }
786 
787 #undef __FUNCT__
788 #define __FUNCT__ "PetscBagSetName"
789 /*@C
790     PetscBagSetName - Sets the name of a bag of values
791 
792   Not Collective
793 
794   Level: Intermediate
795 
796   Input Parameters:
797 +   bag - the bag of values
798 .   name - the name assigned to the bag
799 -   help - help message for bag
800 
801 .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
802            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
803            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
804 @*/
805 
806 PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
807 {
808   PetscErrorCode ierr;
809 
810   PetscFunctionBegin;
811   ierr = PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);CHKERRQ(ierr);
812   ierr = PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);CHKERRQ(ierr);
813   PetscFunctionReturn(0);
814 }
815 
816 
817 #undef __FUNCT__
818 #define __FUNCT__ "PetscBagGetName"
819 /*@C
820     PetscBagGetName - Gets the name of a bag of values
821 
822   Not Collective
823 
824   Level: Intermediate
825 
826   Input Parameter:
827 .   bag - the bag of values
828 
829   Output Parameter:
830 .   name - the name assigned to the bag
831 
832 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
833            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
834            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
835 @*/
836 PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
837 {
838   PetscFunctionBegin;
839   *name = bag->bagname;
840   PetscFunctionReturn(0);
841 }
842 
843 #undef __FUNCT__
844 #define __FUNCT__ "PetscBagGetData"
845 /*@C
846     PetscBagGetData - Gives back the user - access to memory that
847     should be used for storing user-data-structure
848 
849   Not Collective
850 
851   Level: Intermediate
852 
853   Input Parameter:
854 .   bag - the bag of values
855 
856   Output Parameter:
857 .   data - pointer to memory that will have user-data-structure
858 
859 .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
860            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
861            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
862 @*/
863 PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
864 {
865   PetscFunctionBegin;
866   *data = bag->structlocation;
867   PetscFunctionReturn(0);
868 }
869 
870 #undef __FUNCT__
871 #define __FUNCT__ "PetscBagSetOptionsPrefix"
872 /*@C
873   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
874   PetscBag items in the options database.
875 
876   Logically collective on Bag.
877 
878   Level: Intermediate
879 
880   Input Parameters:
881 +   bag - the bag of values
882 -   prefix - the prefix to prepend all Bag item names with.
883 
884   NOTES: Must be called prior to registering any of the bag items.
885 
886 .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
887            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
888 @*/
889 
890 PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
891 {
892   PetscErrorCode ierr;
893 
894   PetscFunctionBegin;
895   if (!pre) {
896     ierr = PetscFree(bag->bagprefix);CHKERRQ(ierr);
897   } else {
898     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
899     ierr = PetscFree(bag->bagprefix);CHKERRQ(ierr);
900     ierr = PetscStrallocpy(pre,&(bag->bagprefix));CHKERRQ(ierr);
901   }
902   PetscFunctionReturn(0);
903 }
904