Actual source code: bag.c

  1: #define PETSC_DLL

 3:  #include ../src/sys/bag/bagimpl.h

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

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

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

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

 40:    Collective on PetscBag

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

 49:    Level: beginner

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

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

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

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

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

 98:    Collective on PetscBag

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

107:    Level: beginner

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

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

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

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

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

149:    Collective on PetscBag

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

159:    Level: beginner

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

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

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

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

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

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

207:    Collective on PetscBag

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

216:    Level: beginner

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

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

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

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

255: /*@C
256:    PetscBagRegisterScalar - add a real value to the bag

258:    Collective on PetscBag

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


268:    Level: beginner

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

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

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

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

307: /*@C
308:    PetscBagRegisterTruth - add a logical value to the bag

310:    Collective on PetscBag

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


320:    Level: beginner

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

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

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

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

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

364:    Collective on PetscBag

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

369:    Level: beginner

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

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

382:   while (nitem) {
383:     item  = nitem->next;
384:     if (nitem->freelist) {
385:       void *v = (void*)nitem->list;
386:       PetscFree(v);
387:     }
388:     PetscFree(nitem);
389:     nitem = item;
390:   }
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(), PetscBagRegisterTruth(), 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_TRUTH) {
445:         PetscTruth *value = (PetscTruth*)(((char*)bag) + nitem->offset);
446:         PetscOptionsTruth(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(), PetscBagRegisterTruth(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
473:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

475: @*/
476: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
477: {
478:   PetscTruth     isascii,isbinary;
480:   PetscBagItem   nitem = bag->bagitems;
481: 
483:   PetscTypeCompare((PetscObject)view,PETSC_VIEWER_ASCII,&isascii);
484:   PetscTypeCompare((PetscObject)view,PETSC_VIEWER_BINARY,&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_TRUTH) {
508:         PetscTruth value = *(PetscTruth*)(((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_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: -  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(), PetscBagRegisterTruth(), 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),bag);
667:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag));
668:   (*bag)->bagsize = bagsize+sizeof(struct _n_PetscBag);
669:   (*bag)->bagcomm = comm;
670:   return(0);
671: }
672: 
675: /*@C
676:     PetscBagSetName - Sets the name of a bag of values

678:   Not Collective

680:   Level: Intermediate

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

687: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
688:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
689:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
690: @*/

692: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
693: {
696:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
697:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
698:   return(0);
699: }

703: /*@C
704:     PetscBagGetName - Gets the name of a bag of values

706:   Not Collective

708:   Level: Intermediate

710:   Input Parameter:
711: .   bag - the bag of values

713:   Output Parameter:
714: .   name - the name assigned to the bag

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

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

731:   Not Collective

733:   Level: Intermediate

735:   Input Parameter:
736: .   bag - the bag of values

738:   Output Parameter:
739: .   data - pointer to memory that will have user-data-structure

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