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:     }

451:     /* process any options handlers added with PetscObjectAddOptionsHandler() */
452:     PetscObjectProcessOptionsHandlers((PetscObject)bag);
453:   PetscOptionsEnd();
454:   return(0);
455: }

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

462:    Collective on PetscBag

464:    Input Parameter:
465: +  bag - the bag of values
466: -  viewer - location to view the values

468:    Level: beginner

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

474: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
475:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
476:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

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

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

556: /*@C
557:    PetscBagLoad - Loads a bag of values from a binary file

559:    Collective on PetscViewer

561:    Input Parameter:
562: .  viewer - file to load values from

564:    Output Parameter:
565: .  bag - the bag of values

567:    Level: beginner

569: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
570:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
571:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

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

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

587:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
588:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
589:   PetscViewerBinaryRead(view,bagsizecount,2,PETSC_INT);
590:   PetscMalloc(bagsizecount[0],bag);
591:   PetscMemzero(*bag,bagsizecount[0]);
592:   (*bag)->bagsize = bagsizecount[0];
593:   PetscObjectGetComm((PetscObject)view,&comm);
594:   (*bag)->bagcomm        = comm;
595:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));

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

600:   PetscViewerBinaryGetSkipOptions(view,&skipoptions);
601:   if (skipoptions) PetscBagInLoad = PETSC_TRUE;

603:   for (i=0; i<bagsizecount[1]; i++) {
604:     PetscViewerBinaryRead(view,offsetdtype,2,PETSC_INT);
605:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
606:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
607:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

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

645: /*@
646:     PetscBagCreate - Create a bag of values

648:   Collective on MPI_Comm

650:   Level: Intermediate

652:   Input Parameters:
653: +  comm - communicator to share bag
654: -  bagsize - size of the C structure holding the values

656:   Output Parameter:
657: .   bag - the bag of values

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

664: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
665:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
666:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
667: @*/
668: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
669: {

673:   PetscMalloc(bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar),bag);
674:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));
675:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
676:   (*bag)->bagcomm        = comm;
677:   (*bag)->bagprefix      = PETSC_NULL;
678:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
679:   return(0);
680: }
681: 
684: /*@C
685:     PetscBagSetName - Sets the name of a bag of values

687:   Not Collective

689:   Level: Intermediate

691:   Input Parameters:
692: +   bag - the bag of values
693: .   name - the name assigned to the bag
694: -   help - help message for bag

696: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
697:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
698:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
699: @*/

701: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
702: {
705:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
706:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
707:   return(0);
708: }


713: /*@C
714:     PetscBagGetName - Gets the name of a bag of values

716:   Not Collective

718:   Level: Intermediate

720:   Input Parameter:
721: .   bag - the bag of values

723:   Output Parameter:
724: .   name - the name assigned to the bag

726: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
727:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
728:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
729: @*/
730: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
731: {
733:   *name = bag->bagname;
734:   return(0);
735: }

739: /*@C
740:     PetscBagGetData - Gives back the user - access to memory that
741:     should be used for storing user-data-structure

743:   Not Collective

745:   Level: Intermediate

747:   Input Parameter:
748: .   bag - the bag of values

750:   Output Parameter:
751: .   data - pointer to memory that will have user-data-structure

753: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
754:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
755:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
756: @*/
757: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
758: {
760:   *data = bag->structlocation;
761:   return(0);
762: }

766: /*@C
767:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
768:   PetscBag items in the options database.

770:   Logically collective on Bag.

772:   Level: Intermediate

774:   Input Parameters:
775: +   bag - the bag of values
776: -   prefix - the prefix to prepend all Bag item names with.

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

780: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
781:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
782: @*/

784: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
785: {
788:   if (!pre) {
789:     PetscFree(bag->bagprefix);
790:   } else {
791:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
792:     PetscFree(bag->bagprefix);
793:     PetscStrallocpy(pre,&(bag->bagprefix));
794:   }
795:   return(0);
796: }