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

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

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

366:    Collective on PetscBag

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

371:    Level: beginner

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

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

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

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

402:    Collective on PetscBag

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

407:    Level: beginner

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

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

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

461:    Collective on PetscBag

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

467:    Level: beginner

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

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

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

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

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

558:    Collective on PetscViewer

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

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

566:    Level: beginner

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

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

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

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

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

595:   PetscViewerBinaryGetSkipOptions(view,&skipoptions);
596:   if (skipoptions) PetscBagInLoad = PETSC_TRUE;

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

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

640: /*@
641:     PetscBagCreate - Create a bag of values

643:   Collective on MPI_Comm

645:   Level: Intermediate

647:   Input Parameters:
648: +  comm - communicator to share bag
649: -  size - size of the C structure holding the values

651:   Output Parameter:
652: .   bag - the bag of values

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

659: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
660:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
661:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
662: @*/
663: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t size, PetscBag *bag)
664: {
666:   size_t tsize;

669:   tsize = sizeof(struct _n_PetscBag)+size;
670:   PetscMalloc(tsize,bag);
671:   PetscMemzero(*bag,tsize);
672:   (*bag)->bagsize = tsize;
673:   (*bag)->bagcomm = comm;
674:   return(0);
675: }
676: 
679: /*@C
680:     PetscBagSetName - Sets the name of a bag of values

682:   Not Collective

684:   Level: Intermediate

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

691: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
692:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterTruth(), PetscBagRegisterScalar()
693:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
694: @*/

696: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
697: {
700:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
701:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
702:   return(0);
703: }

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

710:   Not Collective

712:   Level: Intermediate

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

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

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

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

735:   Not Collective

737:   Level: Intermediate

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

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

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