Actual source code: bag.c

  1: #define PETSC_DLL

 3:  #include petsc.h
 4:  #include petscsys.h
 5:  #include ../src/sys/bag/bagimpl.h

  7: /*
  8:    Ugly variable to indicate if we are inside a PetscBagLoad() and should not call PetscOptions....
  9: */
 10: static PetscTruth PetscBagInLoad = PETSC_FALSE;

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

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

 39: /*@C
 40:    PetscBagRegisterEnum - add an enum value to the bag

 42:    Collective on PetscBag

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

 51:    Level: beginner

 53: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 54:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
 55:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

 57: @*/
 58: PetscErrorCode PetscBagRegisterEnum(PetscBag bag,void *addr,const char **list,PetscEnum mdefault, const char *name, const char* help)
 59: {
 61:   PetscBagItem   item;
 62:   char           nname[PETSC_BAG_NAME_LENGTH+1];
 63:   PetscTruth     printhelp;
 64:   PetscInt       i = 0;

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

 83:   PetscNew(struct _n_PetscBagItem,&item);
 84:   item->dtype  = PETSC_ENUM;
 85:   item->offset = ((char*)addr) - ((char*)bag);
 86:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
 87:   item->next   = 0;
 88:   item->msize  = 1;
 89:   item->list   = list;
 90:   *(PetscEnum*)addr = mdefault;
 91:   PetscBagRegister_Private(bag,item,name,help);
 92:   return(0);
 93: }

 97: /*@C
 98:    PetscBagRegisterInt - add an integer value to the bag

100:    Collective on PetscBag

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

109:    Level: beginner

111: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
112:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
113:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

115: @*/
116: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault, const char* name, const char* help)
117: {
119:   PetscBagItem   item;
120:   char           nname[PETSC_BAG_NAME_LENGTH+1];
121:   PetscTruth     printhelp;

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

135:   PetscNew(struct _n_PetscBagItem,&item);
136:   item->dtype  = PETSC_INT;
137:   item->offset = ((char*)addr) - ((char*)bag);
138:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
139:   item->next   = 0;
140:   item->msize  = 1;
141:   *(PetscInt*)addr = mdefault;
142:   PetscBagRegister_Private(bag,item,name,help);
143:   return(0);
144: }

148: /*@C
149:    PetscBagRegisterString - add a string value to the bag

151:    Collective on PetscBag

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

161:    Level: beginner

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

165: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
166:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
167:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

169: @*/
170: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault, const char* name, const char* help)
171: {
173:   PetscBagItem   item;
174:   char           nname[PETSC_BAG_NAME_LENGTH+1];
175:   PetscTruth     printhelp;

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

188:   PetscNew(struct _n_PetscBagItem,&item);
189:   item->dtype  = PETSC_CHAR;
190:   item->offset = ((char*)addr) - ((char*)bag);
191:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
192:   item->next   = 0;
193:   item->msize  = msize;
194:   if (mdefault != (char*)addr) {
195:     PetscStrncpy((char*)addr,mdefault,msize-1);
196:   }
197:   if (!PetscBagInLoad) {
198:     PetscOptionsGetString(PETSC_NULL,nname,(char*)addr,msize,PETSC_NULL);
199:   }
200:   PetscBagRegister_Private(bag,item,name,help);
201:   return(0);
202: }

206: /*@C
207:    PetscBagRegisterReal - add a real value to the bag

209:    Collective on PetscBag

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

218:    Level: beginner

220: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
221:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
222:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

224: @*/
225: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char* name, const char* help)
226: {
228:   PetscBagItem   item;
229:   char           nname[PETSC_BAG_NAME_LENGTH+1];
230:   PetscTruth     printhelp;

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

244:   PetscNew(struct _n_PetscBagItem,&item);
245:   item->dtype  = PETSC_REAL;
246:   item->offset = ((char*)addr) - ((char*)bag);
247:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
248:   item->next   = 0;
249:   item->msize  = 1;
250:   *(PetscReal*)addr = mdefault;
251:   PetscBagRegister_Private(bag,item,name,help);
252:   return(0);
253: }

257: /*@C
258:    PetscBagRegisterScalar - add a real value to the bag

260:    Collective on PetscBag

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


270:    Level: beginner

272: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
273:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
274:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

276: @*/
277: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault, const char* name, const char* help)
278: {
280:   PetscBagItem   item;
281:   char           nname[PETSC_BAG_NAME_LENGTH+1];
282:   PetscTruth     printhelp;

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

296:   PetscNew(struct _n_PetscBagItem,&item);
297:   item->dtype  = PETSC_SCALAR;
298:   item->offset = ((char*)addr) - ((char*)bag);
299:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
300:   item->next   = 0;
301:   item->msize  = 1;
302:   *(PetscScalar*)addr = mdefault;
303:   PetscBagRegister_Private(bag,item,name,help);
304:   return(0);
305: }

309: /*@C
310:    PetscBagRegisterTruth - add a logical value to the bag

312:    Collective on PetscBag

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


322:    Level: beginner

324: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
325:            PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
326:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

328: @*/
329: PetscErrorCode PetscBagRegisterTruth(PetscBag bag,void *addr,PetscTruth mdefault, const char* name, const char* help)
330: {
332:   PetscBagItem   item;
333:   char           nname[PETSC_BAG_NAME_LENGTH+1];
334:   PetscTruth     printhelp;

337:   if (mdefault != PETSC_FALSE && mdefault != PETSC_TRUE) SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Boolean %s %s must be boolean; integer value %d",name,help,(int)mdefault);
338:   if (!PetscBagInLoad) {
339:     nname[0] = '-';
340:     nname[1] = 0;
341:     PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
342:     PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
343:     if (printhelp) {
344:       (*PetscHelpPrintf)(bag->bagcomm,"  %s <%s>: %s \n",nname,PetscTruths[mdefault],help);
345:     }
346:     PetscOptionsGetTruth(PETSC_NULL,nname,&mdefault,PETSC_NULL);
347:   }

349:   PetscNew(struct _n_PetscBagItem,&item);
350:   item->dtype  = PETSC_TRUTH;
351:   item->offset = ((char*)addr) - ((char*)bag);
352:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
353:   item->next   = 0;
354:   item->msize  = 1;
355:   *(PetscTruth*)addr = mdefault;
356:   PetscBagRegister_Private(bag,item,name,help);
357:   return(0);
358: }

362: /*@C
363:    PetscBagDestroy - Destroys a bag values

365:    Collective on PetscBag

367:    Input Parameter:
368: .  bag - the bag of values

370:    Level: beginner

372: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
373:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
374:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

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

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

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

401:    Collective on PetscBag

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

406:    Level: beginner

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

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

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

460:    Collective on PetscBag

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

466:    Level: beginner

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

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

476: @*/
477: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
478: {
479:   PetscTruth     isascii,isbinary;
481:   PetscBagItem   nitem = bag->bagitems;
482: 
484:   PetscTypeCompare((PetscObject)view,PETSC_VIEWER_ASCII,&isascii);
485:   PetscTypeCompare((PetscObject)view,PETSC_VIEWER_BINARY,&isbinary);
486:   if (isascii) {
487:     PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
488:     while (nitem) {
489:       if (nitem->dtype == PETSC_CHAR) {
490:         char* value = (char*)(((char*)bag) + nitem->offset);
491:         char tmp = value[nitem->msize-1];  /* special handling for fortran chars wihout null terminator */
492:         value[nitem->msize-1] =0;
493:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
494:         value[nitem->msize-1] =tmp;
495:       } else if (nitem->dtype == PETSC_REAL) {
496:         PetscReal value = *(PetscReal*)(((char*)bag) + nitem->offset);
497:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
498:       } else if (nitem->dtype == PETSC_SCALAR) {
499:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
500: #if defined(PETSC_USE_COMPLEX)
501:         PetscViewerASCIIPrintf(view,"  %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);
502: #else
503:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
504: #endif
505:       } else if (nitem->dtype == PETSC_INT) {
506:         PetscInt value = *(PetscInt*)(((char*)bag) + nitem->offset);
507:         PetscViewerASCIIPrintf(view,"  %s = %D; %s\n",nitem->name,value,nitem->help);
508:       } else if (nitem->dtype == PETSC_TRUTH) {
509:         PetscTruth value = *(PetscTruth*)(((char*)bag) + nitem->offset);
510:         /* some Fortran compilers use -1 as boolean */
511:         if (((int) value) == -1) value = PETSC_TRUE;
512:         if (value != PETSC_FALSE && value != PETSC_TRUE) SETERRQ3(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,PetscTruths[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 cookie = PETSC_BAG_FILE_COOKIE, bagsize = (PetscInt) bag->bagsize, dtype;
524:     PetscViewerBinaryWrite(view,&cookie,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_TRUTH && ((*(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_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(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
568:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

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

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

583:   PetscViewerBinaryRead(view,&cookie,1,PETSC_INT);
584:   if (cookie != PETSC_BAG_FILE_COOKIE) SETERRQ(PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
585:   PetscViewerBinaryRead(view,bagsizecount,2,PETSC_INT);
586:   PetscMalloc(bagsizecount[0],bag);
587:   PetscMemzero(*bag,bagsizecount[0]);
588:   (*bag)->bagsize = bagsizecount[0];

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_TRUTH) {
618:       PetscTruth mdefault;
619:       PetscViewerBinaryRead(view,&mdefault,1,PETSC_TRUTH);
620:       PetscBagRegisterTruth(*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: -  size - 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(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
659:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
660: @*/
661: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t size, PetscBag *bag)
662: {
664:   size_t tsize;

667:   tsize = sizeof(struct _n_PetscBag)+size;
668:   PetscMalloc(tsize,bag);
669:   PetscMemzero(*bag,tsize);
670:   (*bag)->bagsize = tsize;
671:   (*bag)->bagcomm = comm;
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(), PetscBagRegisterTruth(), 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: }

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

708:   Not Collective

710:   Level: Intermediate

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

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

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

729: /*@C
730:     PetscBagGetData - Gives back the user - access to memory that
731:     should be used for storing user-data-structure

733:   Not Collective

735:   Level: Intermediate

737:   Input Parameter:
738: .   bag - the bag of values

740:   Output Parameter:
741: .   data - pointer to memory that will have user-data-structure

743: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
744:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
745:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
746: @*/
747: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
748: {
750:   *data = (char*)bag + sizeof(struct _n_PetscBag);
751:   return(0);
752: }