Actual source code: bag.c

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


  7: /*
  8:       Adds item to the linked list in a bag
  9: */
 10: static PetscErrorCode PetscBagRegister_Private(PetscBag bag,PetscBagItem item,const char*name,const char*help)
 11: {

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

 32: /*@C
 33:    PetscBagRegisterEnum - add an enum value to the bag

 35:    Logically Collective on PetscBag

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

 44:    Level: beginner

 46: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 47:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 48:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

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

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

 74:   PetscNew(struct _n_PetscBagItem,&item);
 75:   item->dtype  = PETSC_ENUM;
 76:   item->offset = ((char*)addr) - ((char*)bag);
 77:   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);
 78:   item->next   = 0;
 79:   item->msize  = 1;
 80:   item->list   = list;
 81:   *(PetscEnum*)addr = mdefault;
 82:   PetscBagRegister_Private(bag,item,name,help);
 83:   return(0);
 84: }

 88: /*@C
 89:    PetscBagRegisterInt - add an integer value to the bag

 91:    Logically Collective on PetscBag

 93:    Input Parameter:
 94: +  bag - the bag of values
 95: .  addr - location of integer in struct
 96: .  mdefault - the initial value
 97: .  name - name of the integer
 98: -  help - longer string with more information about the value

100:    Level: beginner

102: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
103:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
104:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

106: @*/
107: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault, const char* name, const char* help)
108: {
110:   PetscBagItem   item;
111:   char           nname[PETSC_BAG_NAME_LENGTH+1];
112:   PetscBool      printhelp;

115:   nname[0] = '-';
116:   nname[1] = 0;
117:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
118:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
119:   if (printhelp) {
120:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
121:   }
122:   PetscOptionsGetInt(bag->bagprefix,nname,&mdefault,PETSC_NULL);

124:   PetscNew(struct _n_PetscBagItem,&item);
125:   item->dtype  = PETSC_INT;
126:   item->offset = ((char*)addr) - ((char*)bag);
127:   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);
128:   item->next   = 0;
129:   item->msize  = 1;
130:   *(PetscInt*)addr = mdefault;
131:   PetscBagRegister_Private(bag,item,name,help);
132:   return(0);
133: }

137: /*@C
138:    PetscBagRegisterString - add a string value to the bag

140:    Logically Collective on PetscBag

142:    Input Parameter:
143: +  bag - the bag of values
144: .  addr - location of start of string in struct
145: .  msize - length of the string space in the struct
146: .  mdefault - the initial value
147: .  name - name of the string
148: -  help - longer string with more information about the value

150:    Level: beginner

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

154: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
155:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
156:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

158: @*/
159: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault, const char* name, const char* help)
160: {
162:   PetscBagItem   item;
163:   char           nname[PETSC_BAG_NAME_LENGTH+1];
164:   PetscBool      printhelp;

167:   nname[0] = '-';
168:   nname[1] = 0;
169:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
170:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
171:   if (printhelp) {
172:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
173:   }

175:   PetscNew(struct _n_PetscBagItem,&item);
176:   item->dtype  = PETSC_CHAR;
177:   item->offset = ((char*)addr) - ((char*)bag);
178:   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);
179:   item->next   = 0;
180:   item->msize  = msize;
181:   if (mdefault != (char*)addr) {
182:     PetscStrncpy((char*)addr,mdefault,msize-1);
183:   }
184:   PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,PETSC_NULL);
185:   PetscBagRegister_Private(bag,item,name,help);
186:   return(0);
187: }

191: /*@C
192:    PetscBagRegisterReal - add a real value to the bag

194:    Logically Collective on PetscBag

196:    Input Parameter:
197: +  bag - the bag of values
198: .  addr - location of double in struct
199: .  mdefault - the initial value
200: .  name - name of the variable
201: -  help - longer string with more information about the value

203:    Level: beginner

205: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
206:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
207:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

209: @*/
210: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char* name, const char* help)
211: {
213:   PetscBagItem   item;
214:   char           nname[PETSC_BAG_NAME_LENGTH+1];
215:   PetscBool      printhelp;

218:   nname[0] = '-';
219:   nname[1] = 0;
220:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
221:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
222:   if (printhelp) {
223:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
224:   }
225:   PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,PETSC_NULL);

227:   PetscNew(struct _n_PetscBagItem,&item);
228:   item->dtype  = PETSC_REAL;
229:   item->offset = ((char*)addr) - ((char*)bag);
230:   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);
231:   item->next   = 0;
232:   item->msize  = 1;
233:   *(PetscReal*)addr = mdefault;
234:   PetscBagRegister_Private(bag,item,name,help);
235:   return(0);
236: }

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

243:    Logically Collective on PetscBag

245:    Input Parameter:
246: +  bag - the bag of values
247: .  addr - location of scalar in struct
248: .  mdefault - the initial value
249: .  name - name of the variable
250: -  help - longer string with more information about the value


253:    Level: beginner

255: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
256:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
257:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

259: @*/
260: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault, const char* name, const char* help)
261: {
263:   PetscBagItem   item;
264:   char           nname[PETSC_BAG_NAME_LENGTH+1];
265:   PetscBool      printhelp;

268:   nname[0] = '-';
269:   nname[1] = 0;
270:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
271:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
272:   if (printhelp) {
273:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G + %Gi>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);
274:   }
275:   PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,PETSC_NULL);

277:   PetscNew(struct _n_PetscBagItem,&item);
278:   item->dtype  = PETSC_SCALAR;
279:   item->offset = ((char*)addr) - ((char*)bag);
280:   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);
281:   item->next   = 0;
282:   item->msize  = 1;
283:   *(PetscScalar*)addr = mdefault;
284:   PetscBagRegister_Private(bag,item,name,help);
285:   return(0);
286: }

290: /*@C
291:    PetscBagRegisterBool - add a logical value to the bag

293:    Logically Collective on PetscBag

295:    Input Parameter:
296: +  bag - the bag of values
297: .  addr - location of logical in struct
298: .  mdefault - the initial value
299: .  name - name of the variable
300: -  help - longer string with more information about the value


303:    Level: beginner

305: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
306:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
307:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

309: @*/
310: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool  mdefault, const char* name, const char* help)
311: {
313:   PetscBagItem   item;
314:   char           nname[PETSC_BAG_NAME_LENGTH+1];
315:   PetscBool      printhelp;

318:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
319:   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);
320:   nname[0] = '-';
321:   nname[1] = 0;
322:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
323:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
324:   if (printhelp) {
325:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscBools[mdefault],help);
326:   }
327:   PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,PETSC_NULL);

329:   PetscNew(struct _n_PetscBagItem,&item);
330:   item->dtype  = PETSC_BOOL;
331:   item->offset = ((char*)addr) - ((char*)bag);
332:   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);
333:   item->next   = 0;
334:   item->msize  = 1;
335:   *(PetscBool*)addr = mdefault;
336:   PetscBagRegister_Private(bag,item,name,help);
337:   return(0);
338: }

342: /*@C
343:    PetscBagDestroy - Destroys a bag values

345:    Collective on PetscBag

347:    Input Parameter:
348: .  bag - the bag of values

350:    Level: beginner

352: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
353:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
354:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

356: @*/
357: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
358: {
360:   PetscBagItem   nitem = (*bag)->bagitems,item;

363:   while (nitem) {
364:     item  = nitem->next;
365:     if (nitem->freelist) {
366:       void *v = (void*)nitem->list;
367:       PetscFree(v);
368:     }
369:     PetscFree(nitem);
370:     nitem = item;
371:   }
372:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
373:   PetscFree(*bag);
374:   return(0);
375: }

379: /*@C
380:    PetscBagSetFromOptions - Allows setting options from a bag

382:    Collective on PetscBag

384:    Input Parameter:
385: .  bag - the bag of values

387:    Level: beginner

389: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
390:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
391:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()

393: @*/
394: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
395: {
397:   PetscBagItem   nitem = bag->bagitems;
398:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
399: 
401:   PetscStrcpy(helpname,bag->bagname);
402:   PetscStrcat(helpname," ");
403:   PetscStrcat(helpname,bag->baghelp);
404:   PetscOptionsBegin(bag->bagcomm,PETSC_NULL,helpname,0);
405:     while (nitem) {
406:       name[0] = '-';
407:       name[1] = 0;
408:       PetscStrcat(name,nitem->name);
409:       if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
410:         char *value = (char*)(((char*)bag) + nitem->offset);
411:         PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,PETSC_NULL);
412:       } else if (nitem->dtype == PETSC_REAL) {
413:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
414:         PetscOptionsReal(name,nitem->help,"",*value,value,PETSC_NULL);
415:       } else if (nitem->dtype == PETSC_SCALAR) {
416:         PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
417:         PetscOptionsScalar(name,nitem->help,"",*value,value,PETSC_NULL);
418:       } else if (nitem->dtype == PETSC_INT) {
419:         PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
420:         PetscOptionsInt(name,nitem->help,"",*value,value,PETSC_NULL);
421:       } else if (nitem->dtype == PETSC_ENUM) {
422:         PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
423:         PetscInt  i = 0;
424:         while (nitem->list[i++]);
425:         PetscOptionsEnum(name,nitem->help,nitem->list[i-3],nitem->list,*value,value,PETSC_NULL);
426:       } else if (nitem->dtype == PETSC_BOOL) {
427:         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
428:         PetscOptionsBool(name,nitem->help,"",*value,value,PETSC_NULL);
429:       }
430:       nitem = nitem->next;
431:     }
432:   PetscOptionsEnd();
433:   return(0);
434: }

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

441:    Collective on PetscBag

443:    Input Parameter:
444: +  bag - the bag of values
445: -  viewer - location to view the values

447:    Level: beginner

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

453: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
454:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
455:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

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

520:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
521:       if (dtype == PETSC_ENUM) {
522:         PetscViewerBinaryWriteStringArray(view,(char **)nitem->list);
523:       }
524:       nitem = nitem->next;
525:     }
526:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
527:   return(0);
528: }

532: /*@C
533:    PetscBagLoad - Loads a bag of values from a binary file

535:    Collective on PetscViewer

537:    Input Parameter:
538: +  viewer - file to load values from
539: -  bag - the bag of values

541:    Notes: You must have created and registered all the fields in the bag before loading into it.

543:    Notes: 
544:    Level: beginner

546: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
547:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
548:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

550: @*/
551: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
552: {
554:   PetscBool      isbinary;
555:   PetscInt       classid,bagcount,i,dtype,msize,offset;
556:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
557:   PetscBagItem   nitem;
558:   MPI_Comm       comm;
559:   PetscMPIInt    flag;

562:   PetscObjectGetComm((PetscObject)view,&comm);
563:   MPI_Comm_compare(comm,bag->bagcomm,&flag);
564:   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the viewer and bag"); \
565:   PetscTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
566:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");

568:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
569:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
570:   PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);
571:   if (bagcount != bag->count) SETERRQ2(comm,PETSC_ERR_ARG_INCOMP,"Bag in file has different number of entries %d then passed in bag %d\n",(int)bagcount,(int)bag->count);
572:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
573:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

575:   nitem = bag->bagitems;
576:   for (i=0; i<bagcount; i++) {
577:     PetscViewerBinaryRead(view,&offset,1,PETSC_INT);
578:     /* ignore the offset in the file */
579:     PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);
580:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
581:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
582:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

584:     if (dtype == (PetscInt) PETSC_CHAR) {
585:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);
586:     } else if (dtype == (PetscInt) PETSC_REAL) {
587:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_REAL);
588:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
589:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);
590:     } else if (dtype == (PetscInt) PETSC_INT) {
591:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_INT);
592:     } else if (dtype == (PetscInt) PETSC_BOOL) {
593:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_BOOL);
594:     } else if (dtype == (PetscInt) PETSC_ENUM) {
595:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);
596:       PetscViewerBinaryReadStringArray(view,&list);
597:       /* don't need to save list because it is already registered in the bag */
598:       PetscFree(list);
599:     }
600:     nitem = nitem->next;
601:   }
602:   return(0);
603: }

607: /*@
608:     PetscBagCreate - Create a bag of values

610:   Collective on MPI_Comm

612:   Level: Intermediate

614:   Input Parameters:
615: +  comm - communicator to share bag
616: -  bagsize - size of the C structure holding the values

618:   Output Parameter:
619: .   bag - the bag of values

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

626: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
627:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
628:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
629: @*/
630: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
631: {
633:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

636:   PetscInfo1(PETSC_NULL,"Creating Bag with total size %d\n",(int)totalsize);
637:   PetscMalloc(totalsize,bag);
638:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));
639:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
640:   (*bag)->bagcomm        = comm;
641:   (*bag)->bagprefix      = PETSC_NULL;
642:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
643:   return(0);
644: }
645: 
648: /*@C
649:     PetscBagSetName - Sets the name of a bag of values

651:   Not Collective

653:   Level: Intermediate

655:   Input Parameters:
656: +   bag - the bag of values
657: .   name - the name assigned to the bag
658: -   help - help message for bag

660: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
661:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
662:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
663: @*/

665: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
666: {
669:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
670:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
671:   return(0);
672: }


677: /*@C
678:     PetscBagGetName - Gets the name of a bag of values

680:   Not Collective

682:   Level: Intermediate

684:   Input Parameter:
685: .   bag - the bag of values

687:   Output Parameter:
688: .   name - the name assigned to the bag

690: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
691:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
692:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
693: @*/
694: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
695: {
697:   *name = bag->bagname;
698:   return(0);
699: }

703: /*@C
704:     PetscBagGetData - Gives back the user - access to memory that
705:     should be used for storing user-data-structure

707:   Not Collective

709:   Level: Intermediate

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

714:   Output Parameter:
715: .   data - pointer to memory that will have user-data-structure

717: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
718:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
719:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
720: @*/
721: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
722: {
724:   *data = bag->structlocation;
725:   return(0);
726: }

730: /*@C
731:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
732:   PetscBag items in the options database.

734:   Logically collective on Bag.

736:   Level: Intermediate

738:   Input Parameters:
739: +   bag - the bag of values
740: -   prefix - the prefix to prepend all Bag item names with.

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

744: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
745:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
746: @*/

748: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
749: {
752:   if (!pre) {
753:     PetscFree(bag->bagprefix);
754:   } else {
755:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
756:     PetscFree(bag->bagprefix);
757:     PetscStrallocpy(pre,&(bag->bagprefix));
758:   }
759:   return(0);
760: }