Actual source code: bag.c

  2: #include <../src/sys/bag/bagimpl.h>     /*I  "petscbag.h"   I*/

  4: /*
  5:    Ugly variable to indicate if we are inside a PetscBagLoad() and should not call PetscOptions....
  6: */
  7: static PetscBool  PetscBagInLoad = PETSC_FALSE;

 11: /*
 12:       Adds item to the linked list in a bag
 13: */
 14: static PetscErrorCode PetscBagRegister_Private(PetscBag bag,PetscBagItem item,const char*name,const char*help)
 15: {

 19:   item->freelist = PETSC_FALSE;
 20:   PetscStrncpy(item->name,name,PETSC_BAG_NAME_LENGTH-1);
 21:   PetscStrncpy(item->help,help,PETSC_BAG_HELP_LENGTH-1);
 22:   if (!bag->bagitems) bag->bagitems = item;
 23:   else {
 24:     PetscBagItem nitem = bag->bagitems;
 25:     while (nitem->next) {
 26:       nitem = nitem->next;
 27:     }
 28:     nitem->next = item;
 29:   }
 30:   bag->count++;
 31:   return(0);
 32: }

 36: /*@C
 37:    PetscBagRegisterEnum - add an enum value to the bag

 39:    Logically Collective on PetscBag

 41:    Input Parameter:
 42: +  bag - the bag of values
 43: .  addr - location of enum in struct
 44: .  mdefault - the initial value
 45: .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
 46: -  help - longer string with more information about the value

 48:    Level: beginner

 50: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 51:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 52:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

 54: @*/
 55: PetscErrorCode PetscBagRegisterEnum(PetscBag bag,void *addr,const char **list,PetscEnum mdefault, const char *name, const char* help)
 56: {
 58:   PetscBagItem   item;
 59:   char           nname[PETSC_BAG_NAME_LENGTH+1];
 60:   PetscBool      printhelp;
 61:   PetscInt       i = 0;

 64:   if (!PetscBagInLoad) {
 65:     nname[0] = '-';
 66:     nname[1] = 0;
 67:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
 68:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
 69:     if (printhelp) {
 70:       while (list[i++]);
 71:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: (%s) %s (choose one of) ",bag->bagprefix?bag->bagprefix:"",name,list[mdefault],list[i-3],help);
 72:       for (i=0; list[i+2]; i++){
 73:         (*PetscHelpPrintf)(bag->bagcomm," %s",list[i]);
 74:       }
 75:       (*PetscHelpPrintf)(bag->bagcomm,"\n");
 76:     }
 77:     PetscOptionsGetEnum(bag->bagprefix,nname,list,&mdefault,PETSC_NULL);
 78:   }

 80:   PetscNew(struct _n_PetscBagItem,&item);
 81:   item->dtype  = PETSC_ENUM;
 82:   item->offset = ((char*)addr) - ((char*)bag);
 83:   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);
 84:   item->next   = 0;
 85:   item->msize  = 1;
 86:   item->list   = list;
 87:   *(PetscEnum*)addr = mdefault;
 88:   PetscBagRegister_Private(bag,item,name,help);
 89:   return(0);
 90: }

 94: /*@C
 95:    PetscBagRegisterInt - add an integer value to the bag

 97:    Logically Collective on PetscBag

 99:    Input Parameter:
100: +  bag - the bag of values
101: .  addr - location of integer in struct
102: .  mdefault - the initial value
103: .  name - name of the integer
104: -  help - longer string with more information about the value

106:    Level: beginner

108: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
109:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
110:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

112: @*/
113: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault, const char* name, const char* help)
114: {
116:   PetscBagItem   item;
117:   char           nname[PETSC_BAG_NAME_LENGTH+1];
118:   PetscBool      printhelp;

121:   if (!PetscBagInLoad) {
122:     nname[0] = '-';
123:     nname[1] = 0;
124:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
125:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
126:     if (printhelp) {
127:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
128:     }
129:     PetscOptionsGetInt(bag->bagprefix,nname,&mdefault,PETSC_NULL);
130:   }

132:   PetscNew(struct _n_PetscBagItem,&item);
133:   item->dtype  = PETSC_INT;
134:   item->offset = ((char*)addr) - ((char*)bag);
135:   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);
136:   item->next   = 0;
137:   item->msize  = 1;
138:   *(PetscInt*)addr = mdefault;
139:   PetscBagRegister_Private(bag,item,name,help);
140:   return(0);
141: }

145: /*@C
146:    PetscBagRegisterString - add a string value to the bag

148:    Logically Collective on PetscBag

150:    Input Parameter:
151: +  bag - the bag of values
152: .  addr - location of start of string in struct
153: .  msize - length of the string space in the struct
154: .  mdefault - the initial value
155: .  name - name of the string
156: -  help - longer string with more information about the value

158:    Level: beginner

160:    Note: The struct should have the field char mystring[msize]; not char *mystring

162: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
163:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
164:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

166: @*/
167: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault, const char* name, const char* help)
168: {
170:   PetscBagItem   item;
171:   char           nname[PETSC_BAG_NAME_LENGTH+1];
172:   PetscBool      printhelp;

175:   if (!PetscBagInLoad) {
176:     nname[0] = '-';
177:     nname[1] = 0;
178:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
179:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
180:     if (printhelp) {
181:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
182:     }
183:   }

185:   PetscNew(struct _n_PetscBagItem,&item);
186:   item->dtype  = PETSC_CHAR;
187:   item->offset = ((char*)addr) - ((char*)bag);
188:   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);
189:   item->next   = 0;
190:   item->msize  = msize;
191:   if (mdefault != (char*)addr) {
192:     PetscStrncpy((char*)addr,mdefault,msize-1);
193:   }
194:   if (!PetscBagInLoad) {
195:     PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,PETSC_NULL);
196:   }
197:   PetscBagRegister_Private(bag,item,name,help);
198:   return(0);
199: }

203: /*@C
204:    PetscBagRegisterReal - add a real value to the bag

206:    Logically Collective on PetscBag

208:    Input Parameter:
209: +  bag - the bag of values
210: .  addr - location of double in struct
211: .  mdefault - the initial value
212: .  name - name of the variable
213: -  help - longer string with more information about the value

215:    Level: beginner

217: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
218:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
219:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

221: @*/
222: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char* name, const char* help)
223: {
225:   PetscBagItem   item;
226:   char           nname[PETSC_BAG_NAME_LENGTH+1];
227:   PetscBool      printhelp;

230:   if (!PetscBagInLoad) {
231:     nname[0] = '-';
232:     nname[1] = 0;
233:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
234:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
235:     if (printhelp) {
236:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
237:     }
238:     PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,PETSC_NULL);
239:   }

241:   PetscNew(struct _n_PetscBagItem,&item);
242:   item->dtype  = PETSC_REAL;
243:   item->offset = ((char*)addr) - ((char*)bag);
244:   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);
245:   item->next   = 0;
246:   item->msize  = 1;
247:   *(PetscReal*)addr = mdefault;
248:   PetscBagRegister_Private(bag,item,name,help);
249:   return(0);
250: }

254: /*@C
255:    PetscBagRegisterScalar - add a real or complex number value to the bag

257:    Logically Collective on PetscBag

259:    Input Parameter:
260: +  bag - the bag of values
261: .  addr - location of scalar in struct
262: .  mdefault - the initial value
263: .  name - name of the variable
264: -  help - longer string with more information about the value


267:    Level: beginner

269: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
270:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
271:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

273: @*/
274: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault, const char* name, const char* help)
275: {
277:   PetscBagItem   item;
278:   char           nname[PETSC_BAG_NAME_LENGTH+1];
279:   PetscBool      printhelp;

282:   if (!PetscBagInLoad) {
283:     nname[0] = '-';
284:     nname[1] = 0;
285:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
286:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
287:     if (printhelp) {
288:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G + %Gi>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);
289:     }
290:     PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,PETSC_NULL);
291:   }

293:   PetscNew(struct _n_PetscBagItem,&item);
294:   item->dtype  = PETSC_SCALAR;
295:   item->offset = ((char*)addr) - ((char*)bag);
296:   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);
297:   item->next   = 0;
298:   item->msize  = 1;
299:   *(PetscScalar*)addr = mdefault;
300:   PetscBagRegister_Private(bag,item,name,help);
301:   return(0);
302: }

306: /*@C
307:    PetscBagRegisterBool - add a logical value to the bag

309:    Logically Collective on PetscBag

311:    Input Parameter:
312: +  bag - the bag of values
313: .  addr - location of logical in struct
314: .  mdefault - the initial value
315: .  name - name of the variable
316: -  help - longer string with more information about the value


319:    Level: beginner

321: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
322:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
323:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

325: @*/
326: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool  mdefault, const char* name, const char* help)
327: {
329:   PetscBagItem   item;
330:   char           nname[PETSC_BAG_NAME_LENGTH+1];
331:   PetscBool      printhelp;

334:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
335:   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);
336:   if (!PetscBagInLoad) {
337:     nname[0] = '-';
338:     nname[1] = 0;
339:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
340:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
341:     if (printhelp) {
342:       (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscBools[mdefault],help);
343:     }
344:     PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,PETSC_NULL);
345:   }

347:   PetscNew(struct _n_PetscBagItem,&item);
348:   item->dtype  = PETSC_BOOL;
349:   item->offset = ((char*)addr) - ((char*)bag);
350:   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);
351:   item->next   = 0;
352:   item->msize  = 1;
353:   *(PetscBool*)addr = mdefault;
354:   PetscBagRegister_Private(bag,item,name,help);
355:   return(0);
356: }

360: /*@C
361:    PetscBagDestroy - Destroys a bag values

363:    Collective on PetscBag

365:    Input Parameter:
366: .  bag - the bag of values

368:    Level: beginner

370: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
371:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
372:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

374: @*/
375: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
376: {
378:   PetscBagItem   nitem = (*bag)->bagitems,item;

381:   while (nitem) {
382:     item  = nitem->next;
383:     if (nitem->freelist) {
384:       void *v = (void*)nitem->list;
385:       PetscFree(v);
386:     }
387:     PetscFree(nitem);
388:     nitem = item;
389:   }
390:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
391:   PetscFree(*bag);
392:   return(0);
393: }

397: /*@C
398:    PetscBagSetFromOptions - Allows setting options from a bag

400:    Collective on PetscBag

402:    Input Parameter:
403: .  bag - the bag of values

405:    Level: beginner

407: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
408:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
409:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()

411: @*/
412: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
413: {
415:   PetscBagItem   nitem = bag->bagitems;
416:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
417: 
419:   PetscStrcpy(helpname,bag->bagname);
420:   PetscStrcat(helpname," ");
421:   PetscStrcat(helpname,bag->baghelp);
422:   PetscOptionsBegin(bag->bagcomm,PETSC_NULL,helpname,0);
423:     while (nitem) {
424:       name[0] = '-';
425:       name[1] = 0;
426:       PetscStrcat(name,nitem->name);
427:       if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
428:         char *value = (char*)(((char*)bag) + nitem->offset);
429:         PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,PETSC_NULL);
430:       } else if (nitem->dtype == PETSC_REAL) {
431:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
432:         PetscOptionsReal(name,nitem->help,"",*value,value,PETSC_NULL);
433:       } else if (nitem->dtype == PETSC_SCALAR) {
434:         PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
435:         PetscOptionsScalar(name,nitem->help,"",*value,value,PETSC_NULL);
436:       } else if (nitem->dtype == PETSC_INT) {
437:         PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
438:         PetscOptionsInt(name,nitem->help,"",*value,value,PETSC_NULL);
439:       } else if (nitem->dtype == PETSC_ENUM) {
440:         PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
441:         PetscInt  i = 0;
442:         while (nitem->list[i++]);
443:         PetscOptionsEnum(name,nitem->help,nitem->list[i-3],nitem->list,*value,value,PETSC_NULL);
444:       } else if (nitem->dtype == PETSC_BOOL) {
445:         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
446:         PetscOptionsBool(name,nitem->help,"",*value,value,PETSC_NULL);
447:       }
448:       nitem = nitem->next;
449:     }
450:   PetscOptionsEnd();
451:   return(0);
452: }

456: /*@C
457:    PetscBagView - Views a bag of values as either ASCII text or a binary file

459:    Collective on PetscBag

461:    Input Parameter:
462: +  bag - the bag of values
463: -  viewer - location to view the values

465:    Level: beginner

467:    Warning: Currently PETSc bags saved in a binary file can only be read back
468:      in on a machine of the same architecture. Let us know when this is a problem
469:      and we'll fix it.

471: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
472:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
473:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

475: @*/
476: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
477: {
478:   PetscBool      isascii,isbinary;
480:   PetscBagItem   nitem = bag->bagitems;
481: 
483:   PetscTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
484:   PetscTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
485:   if (isascii) {
486:     PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
487:     while (nitem) {
488:       if (nitem->dtype == PETSC_CHAR) {
489:         char* value = (char*)(((char*)bag) + nitem->offset);
490:         char tmp = value[nitem->msize-1];  /* special handling for fortran chars wihout null terminator */
491:         value[nitem->msize-1] =0;
492:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
493:         value[nitem->msize-1] =tmp;
494:       } else if (nitem->dtype == PETSC_REAL) {
495:         PetscReal value = *(PetscReal*)(((char*)bag) + nitem->offset);
496:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
497:       } else if (nitem->dtype == PETSC_SCALAR) {
498:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
499: #if defined(PETSC_USE_COMPLEX)
500:         PetscViewerASCIIPrintf(view,"  %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);
501: #else
502:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
503: #endif
504:       } else if (nitem->dtype == PETSC_INT) {
505:         PetscInt value = *(PetscInt*)(((char*)bag) + nitem->offset);
506:         PetscViewerASCIIPrintf(view,"  %s = %D; %s\n",nitem->name,value,nitem->help);
507:       } else if (nitem->dtype == PETSC_BOOL) {
508:         PetscBool  value = *(PetscBool*)(((char*)bag) + nitem->offset);
509:         /* some Fortran compilers use -1 as boolean */
510:         if (((int) value) == -1) value = PETSC_TRUE;
511:         /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
512:         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);
513:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,PetscBools[value],nitem->help);
514:       } else if (nitem->dtype == PETSC_ENUM) {
515:         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
516:         PetscInt  i = 0;
517:         while (nitem->list[i++]);
518:         PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
519:       }
520:       nitem = nitem->next;
521:     }
522:   } else if (isbinary) {
523:     PetscInt classid = PETSC_BAG_FILE_CLASSID, bagsize = (PetscInt) bag->bagsize, dtype;
524:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
525:     PetscViewerBinaryWrite(view,&bagsize,1,PETSC_INT,PETSC_TRUE);
526:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
527:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
528:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
529:     while (nitem) {
530:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
531:       dtype = (PetscInt)nitem->dtype;
532:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
533:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
534:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
535:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
536:       /* some Fortran compilers use -1 as boolean */
537:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

539:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
540:       if (dtype == PETSC_ENUM) {
541:         PetscViewerBinaryWriteStringArray(view,(char **)nitem->list);
542:       }
543:       nitem = nitem->next;
544:     }
545:   } else {
546:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
547:   }
548:   return(0);
549: }

553: /*@C
554:    PetscBagLoad - Loads a bag of values from a binary file

556:    Collective on PetscViewer

558:    Input Parameter:
559: .  viewer - file to load values from

561:    Output Parameter:
562: .  bag - the bag of values

564:    Level: beginner

566: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
567:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
568:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

570: @*/
571: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag *bag)
572: {
574:   PetscBool      isbinary,skipoptions;
575:   PetscInt       classid,bagsizecount[2],i,offsetdtype[2],msize;
576:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
577:   PetscBagItem   nitem;
578:   MPI_Comm       comm;

581:   PetscTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
582:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");

584:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
585:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
586:   PetscViewerBinaryRead(view,bagsizecount,2,PETSC_INT);
587:   PetscObjectGetComm((PetscObject)view,&comm);
588:   PetscBagCreate(comm,bagsizecount[0]-sizeof(struct _n_PetscBag)-sizeof(PetscScalar),bag);

590:   PetscViewerBinaryRead(view,(*bag)->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
591:   PetscViewerBinaryRead(view,(*bag)->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

593:   PetscViewerBinaryGetSkipOptions(view,&skipoptions);
594:   if (skipoptions) PetscBagInLoad = PETSC_TRUE;

596:   for (i=0; i<bagsizecount[1]; i++) {
597:     PetscViewerBinaryRead(view,offsetdtype,2,PETSC_INT);
598:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
599:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
600:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

602:     if (offsetdtype[1] == (PetscInt) PETSC_CHAR) {
603:       PetscViewerBinaryRead(view,((char*)(*bag))+offsetdtype[0],msize,PETSC_CHAR);
604:       PetscBagRegisterString(*bag,((char*)(*bag))+offsetdtype[0],msize,((char*)(*bag))+offsetdtype[0],name,help);
605:     } else if (offsetdtype[1] == (PetscInt) PETSC_REAL) {
606:       PetscReal mdefault;
607:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_REAL);
608:       PetscBagRegisterReal(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
609:     } else if (offsetdtype[1] == (PetscInt) PETSC_SCALAR) {
610:       PetscScalar mdefault;
611:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_SCALAR);
612:       PetscBagRegisterScalar(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
613:     } else if (offsetdtype[1] == (PetscInt) PETSC_INT) {
614:       PetscInt mdefault;
615:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_INT);
616:       PetscBagRegisterInt(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
617:     } else if (offsetdtype[1] == (PetscInt) PETSC_BOOL) {
618:       PetscBool  mdefault;
619:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_BOOL);
620:       PetscBagRegisterBool(*bag,((char*)(*bag))+offsetdtype[0],mdefault,name,help);
621:     } else if (offsetdtype[1] == (PetscInt) PETSC_ENUM) {
622:       PetscEnum mdefault;
623:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_ENUM);
624:       PetscViewerBinaryReadStringArray(view,&list);
625:       PetscBagRegisterEnum(*bag,((char*)(*bag))+offsetdtype[0],(const char**)list,mdefault,name,help);
626:       /* we malloced list in PetscViewerBinaryReadStringArray() so must free ourselves */
627:       nitem = (*bag)->bagitems;
628:       while (nitem->next) nitem = nitem->next;
629:       nitem->freelist = PETSC_TRUE;
630:     }
631:   }
632:   PetscBagInLoad = PETSC_FALSE;
633:   return(0);
634: }

638: /*@
639:     PetscBagCreate - Create a bag of values

641:   Collective on MPI_Comm

643:   Level: Intermediate

645:   Input Parameters:
646: +  comm - communicator to share bag
647: -  bagsize - size of the C structure holding the values

649:   Output Parameter:
650: .   bag - the bag of values

652:    Notes:
653:       The size of the A struct must be small enough to fit in a PetscInt; by default
654:       PetscInt is 4 bytes. The warning about casting to a shorter length can be ignored
655:       below unless your A struct is too large

657: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
658:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
659:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
660: @*/
661: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
662: {

666:   PetscMalloc(bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar),bag);
667:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));
668:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
669:   (*bag)->bagcomm        = comm;
670:   (*bag)->bagprefix      = PETSC_NULL;
671:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
672:   return(0);
673: }
674: 
677: /*@C
678:     PetscBagSetName - Sets the name of a bag of values

680:   Not Collective

682:   Level: Intermediate

684:   Input Parameters:
685: +   bag - the bag of values
686: .   name - the name assigned to the bag
687: -   help - help message for bag

689: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
690:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
691:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
692: @*/

694: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
695: {
698:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
699:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
700:   return(0);
701: }


706: /*@C
707:     PetscBagGetName - Gets the name of a bag of values

709:   Not Collective

711:   Level: Intermediate

713:   Input Parameter:
714: .   bag - the bag of values

716:   Output Parameter:
717: .   name - the name assigned to the bag

719: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
720:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
721:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
722: @*/
723: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
724: {
726:   *name = bag->bagname;
727:   return(0);
728: }

732: /*@C
733:     PetscBagGetData - Gives back the user - access to memory that
734:     should be used for storing user-data-structure

736:   Not Collective

738:   Level: Intermediate

740:   Input Parameter:
741: .   bag - the bag of values

743:   Output Parameter:
744: .   data - pointer to memory that will have user-data-structure

746: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
747:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
748:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
749: @*/
750: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
751: {
753:   *data = bag->structlocation;
754:   return(0);
755: }

759: /*@C
760:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
761:   PetscBag items in the options database.

763:   Logically collective on Bag.

765:   Level: Intermediate

767:   Input Parameters:
768: +   bag - the bag of values
769: -   prefix - the prefix to prepend all Bag item names with.

771:   NOTES: Must be called prior to registering any of the bag items.

773: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
774:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
775: @*/

777: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
778: {
781:   if (!pre) {
782:     PetscFree(bag->bagprefix);
783:   } else {
784:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
785:     PetscFree(bag->bagprefix);
786:     PetscStrallocpy(pre,&(bag->bagprefix));
787:   }
788:   return(0);
789: }