Actual source code: bag.c

petsc-3.4.5 2014-06-29
  2: #include <petsc-private/bagimpl.h>     /*I  "petscbag.h"   I*/
  3: #include <petscviewer.h>

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

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

 34:    Logically Collective on PetscBag

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

 43:    Level: beginner

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

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

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

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

 87: /*@C
 88:    PetscBagRegisterIntArray - add an integer value to the bag

 90:    Logically Collective on PetscBag

 92:    Input Parameter:
 93: +  bag - the bag of values
 94: .  addr - location of integer in struct
 95: .  msize - number of entries in array
 96: .  name - name of the integer array
 97: -  help - longer string with more information about the value

 99:    Level: beginner

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

105: @*/
106: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag,void *addr,PetscInt msize, const char *name, const char *help)
107: {
109:   PetscBagItem   item;
110:   char           nname[PETSC_BAG_NAME_LENGTH+1];
111:   PetscBool      printhelp;
112:   PetscInt       i,tmp = msize;

115:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
116:   nname[0] = '-';
117:   nname[1] = 0;
118:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
119:   PetscOptionsHasName(NULL,"-help",&printhelp);
120:   if (printhelp) {
121:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix ? bag->bagprefix : "",name);
122:     for (i=0; i<msize; i++) {
123:       (*PetscHelpPrintf)(bag->bagcomm,"%D ",*((PetscInt*)addr)+i);
124:     }
125:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
126:   }
127:   PetscOptionsGetIntArray(bag->bagprefix,nname,(PetscInt*)addr,&tmp,NULL);

129:   PetscNew(struct _n_PetscBagItem,&item);
130:   item->dtype  = PETSC_INT;
131:   item->offset = ((char*)addr) - ((char*)bag);
132:   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);
133:   item->next  = 0;
134:   item->msize = msize;
135:   PetscBagRegister_Private(bag,item,name,help);
136:   return(0);
137: }

141: /*@C
142:    PetscBagRegisterRealArray - add an real array to the bag

144:    Logically Collective on PetscBag

146:    Input Parameter:
147: +  bag - the bag of values
148: .  addr - location of real array in struct
149: .  msize - number of entries in array
150: .  name - name of the integer array
151: -  help - longer string with more information about the value

153:    Level: beginner

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

159: @*/
160: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag,void *addr,PetscInt msize, const char *name, const char *help)
161: {
163:   PetscBagItem   item;
164:   char           nname[PETSC_BAG_NAME_LENGTH+1];
165:   PetscBool      printhelp;
166:   PetscInt       i,tmp = msize;

169:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
170:   nname[0] = '-';
171:   nname[1] = 0;
172:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
173:   PetscOptionsHasName(NULL,"-help",&printhelp);
174:   if (printhelp) {
175:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix ? bag->bagprefix : "",name);
176:     for (i=0; i<msize; i++) {
177:       (*PetscHelpPrintf)(bag->bagcomm,"%G ",*((PetscReal*)addr)+i);
178:     }
179:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
180:   }
181:   PetscOptionsGetRealArray(bag->bagprefix,nname,(PetscReal*)addr,&tmp,NULL);

183:   PetscNew(struct _n_PetscBagItem,&item);
184:   item->dtype  = PETSC_REAL;
185:   item->offset = ((char*)addr) - ((char*)bag);
186:   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);
187:   item->next  = 0;
188:   item->msize = msize;
189:   PetscBagRegister_Private(bag,item,name,help);
190:   return(0);
191: }

195: /*@C
196:    PetscBagRegisterInt - add an integer value to the bag

198:    Logically Collective on PetscBag

200:    Input Parameter:
201: +  bag - the bag of values
202: .  addr - location of integer in struct
203: .  mdefault - the initial value
204: .  name - name of the integer
205: -  help - longer string with more information about the value

207:    Level: beginner

209: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
210:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
211:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

213: @*/
214: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault,const char *name,const char *help)
215: {
217:   PetscBagItem   item;
218:   char           nname[PETSC_BAG_NAME_LENGTH+1];
219:   PetscBool      printhelp;

222:   nname[0] = '-';
223:   nname[1] = 0;
224:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
225:   PetscOptionsHasName(NULL,"-help",&printhelp);
226:   if (printhelp) {
227:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);
228:   }
229:   PetscOptionsGetInt(bag->bagprefix,nname,&mdefault,NULL);

231:   PetscNew(struct _n_PetscBagItem,&item);
232:   item->dtype  = PETSC_INT;
233:   item->offset = ((char*)addr) - ((char*)bag);
234:   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);
235:   item->next       = 0;
236:   item->msize      = 1;
237:   *(PetscInt*)addr = mdefault;
238:   PetscBagRegister_Private(bag,item,name,help);
239:   return(0);
240: }

244: /*@C
245:    PetscBagRegisterString - add a string value to the bag

247:    Logically Collective on PetscBag

249:    Input Parameter:
250: +  bag - the bag of values
251: .  addr - location of start of string in struct
252: .  msize - length of the string space in the struct
253: .  mdefault - the initial value
254: .  name - name of the string
255: -  help - longer string with more information about the value

257:    Level: beginner

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

261: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
262:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
263:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

265: @*/
266: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault,const char* name,const char* help)
267: {
269:   PetscBagItem   item;
270:   char           nname[PETSC_BAG_NAME_LENGTH+1];
271:   PetscBool      printhelp;

274:   nname[0] = '-';
275:   nname[1] = 0;
276:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
277:   PetscOptionsHasName(NULL,"-help",&printhelp);
278:   if (printhelp) {
279:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);
280:   }

282:   PetscNew(struct _n_PetscBagItem,&item);
283:   item->dtype  = PETSC_CHAR;
284:   item->offset = ((char*)addr) - ((char*)bag);
285:   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);
286:   item->next  = 0;
287:   item->msize = msize;
288:   if (mdefault != (char*)addr) {
289:     PetscStrncpy((char*)addr,mdefault,msize-1);
290:   }
291:   PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,NULL);
292:   PetscBagRegister_Private(bag,item,name,help);
293:   return(0);
294: }

298: /*@C
299:    PetscBagRegisterReal - add a real value to the bag

301:    Logically Collective on PetscBag

303:    Input Parameter:
304: +  bag - the bag of values
305: .  addr - location of double in struct
306: .  mdefault - the initial value
307: .  name - name of the variable
308: -  help - longer string with more information about the value

310:    Level: beginner

312: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
313:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
314:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

316: @*/
317: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char *name, const char *help)
318: {
320:   PetscBagItem   item;
321:   char           nname[PETSC_BAG_NAME_LENGTH+1];
322:   PetscBool      printhelp;

325:   nname[0] = '-';
326:   nname[1] = 0;
327:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
328:   PetscOptionsHasName(NULL,"-help",&printhelp);
329:   if (printhelp) {
330:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);
331:   }
332:   PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,NULL);

334:   PetscNew(struct _n_PetscBagItem,&item);
335:   item->dtype  = PETSC_REAL;
336:   item->offset = ((char*)addr) - ((char*)bag);
337:   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);
338:   item->next        = 0;
339:   item->msize       = 1;
340:   *(PetscReal*)addr = mdefault;
341:   PetscBagRegister_Private(bag,item,name,help);
342:   return(0);
343: }

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

350:    Logically Collective on PetscBag

352:    Input Parameter:
353: +  bag - the bag of values
354: .  addr - location of scalar in struct
355: .  mdefault - the initial value
356: .  name - name of the variable
357: -  help - longer string with more information about the value


360:    Level: beginner

362: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
363:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
364:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

366: @*/
367: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
368: {
370:   PetscBagItem   item;
371:   char           nname[PETSC_BAG_NAME_LENGTH+1];
372:   PetscBool      printhelp;

375:   nname[0] = '-';
376:   nname[1] = 0;
377:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
378:   PetscOptionsHasName(NULL,"-help",&printhelp);
379:   if (printhelp) {
380:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G + %Gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);
381:   }
382:   PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,NULL);

384:   PetscNew(struct _n_PetscBagItem,&item);
385:   item->dtype  = PETSC_SCALAR;
386:   item->offset = ((char*)addr) - ((char*)bag);
387:   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);
388:   item->next          = 0;
389:   item->msize         = 1;
390:   *(PetscScalar*)addr = mdefault;
391:   PetscBagRegister_Private(bag,item,name,help);
392:   return(0);
393: }

397: /*@C
398:    PetscBagRegisterBool - add a logical value to the bag

400:    Logically Collective on PetscBag

402:    Input Parameter:
403: +  bag - the bag of values
404: .  addr - location of logical in struct
405: .  mdefault - the initial value
406: .  name - name of the variable
407: -  help - longer string with more information about the value


410:    Level: beginner

412: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
413:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
414:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

416: @*/
417: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
418: {
420:   PetscBagItem   item;
421:   char           nname[PETSC_BAG_NAME_LENGTH+1];
422:   PetscBool      printhelp;

425:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
426:   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);
427:   nname[0] = '-';
428:   nname[1] = 0;
429:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
430:   PetscOptionsHasName(NULL,"-help",&printhelp);
431:   if (printhelp) {
432:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);
433:   }
434:   PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,NULL);

436:   PetscNew(struct _n_PetscBagItem,&item);
437:   item->dtype  = PETSC_BOOL;
438:   item->offset = ((char*)addr) - ((char*)bag);
439:   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);
440:   item->next        = 0;
441:   item->msize       = 1;
442:   *(PetscBool*)addr = mdefault;
443:   PetscBagRegister_Private(bag,item,name,help);
444:   return(0);
445: }

449: /*@C
450:    PetscBagDestroy - Destroys a bag values

452:    Collective on PetscBag

454:    Input Parameter:
455: .  bag - the bag of values

457:    Level: beginner

459: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
460:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
461:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

463: @*/
464: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
465: {
467:   PetscBagItem   nitem = (*bag)->bagitems,item;

470:   while (nitem) {
471:     item = nitem->next;
472:     if (nitem->list) {
473:       PetscStrArrayDestroy(&nitem->list);
474:     }
475:     PetscFree(nitem);
476:     nitem = item;
477:   }
478:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
479:   PetscFree(*bag);
480:   return(0);
481: }

485: /*@
486:    PetscBagSetFromOptions - Allows setting options from a bag

488:    Collective on PetscBag

490:    Input Parameter:
491: .  bag - the bag of values

493:    Level: beginner

495: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
496:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
497:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()

499: @*/
500: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
501: {
503:   PetscBagItem   nitem = bag->bagitems;
504:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
505:   PetscInt       n;

508:   PetscStrcpy(helpname,bag->bagname);
509:   PetscStrcat(helpname," ");
510:   PetscStrcat(helpname,bag->baghelp);
511:   PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,0);
512:   while (nitem) {
513:     name[0] = '-';
514:     name[1] = 0;
515:     PetscStrcat(name,nitem->name);
516:     if (nitem->dtype == PETSC_CHAR) {   /* special handling for fortran required? [due to space padding vs null termination] */
517:       char *value = (char*)(((char*)bag) + nitem->offset);
518:       PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,NULL);
519:     } else if (nitem->dtype == PETSC_REAL) {
520:       PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
521:       if (nitem->msize == 1) {
522:         PetscOptionsReal(name,nitem->help,"",*value,value,NULL);
523:       } else {
524:         n    = nitem->msize;
525:         PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);
526:       }
527:     } else if (nitem->dtype == PETSC_SCALAR) {
528:       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
529:       PetscOptionsScalar(name,nitem->help,"",*value,value,NULL);
530:     } else if (nitem->dtype == PETSC_INT) {
531:       PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
532:       if (nitem->msize == 1) {
533:         PetscOptionsInt(name,nitem->help,"",*value,value,NULL);
534:       } else {
535:         n    = nitem->msize;
536:         PetscOptionsIntArray(name,nitem->help,"",value,&n,NULL);
537:       }
538:     } else if (nitem->dtype == PETSC_ENUM) {
539:       PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
540:       PetscInt  i      = 0;
541:       while (nitem->list[i++]) ;
542:       PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,NULL);
543:     } else if (nitem->dtype == PETSC_BOOL) {
544:       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
545:       PetscOptionsBool(name,nitem->help,"",*value,value,NULL);
546:     }
547:     nitem = nitem->next;
548:   }
549:   PetscOptionsEnd();
550:   return(0);
551: }

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

558:    Collective on PetscBag

560:    Input Parameter:
561: +  bag - the bag of values
562: -  viewer - location to view the values

564:    Level: beginner

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

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

574: @*/
575: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
576: {
577:   PetscBool      isascii,isbinary;
579:   PetscBagItem   nitem = bag->bagitems;

582:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
583:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
584:   if (isascii) {
585:     PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
586:     while (nitem) {
587:       if (nitem->dtype == PETSC_CHAR) {
588:         char *value = (char*)(((char*)bag) + nitem->offset);
589:         char tmp    = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
590:         value[nitem->msize-1] =0;
591:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
592:         value[nitem->msize-1] = tmp;
593:       } else if (nitem->dtype == PETSC_REAL) {
594:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
595:         PetscInt  i;
596:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
597:         for (i=0; i<nitem->msize; i++) {
598:           PetscViewerASCIIPrintf(view,"%G ",value[i]);
599:         }
600:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
601:       } else if (nitem->dtype == PETSC_SCALAR) {
602:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
603: #if defined(PETSC_USE_COMPLEX)
604:         PetscViewerASCIIPrintf(view,"  %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);
605: #else
606:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
607: #endif
608:       } else if (nitem->dtype == PETSC_INT) {
609:         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
610:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
611:         for (i=0; i<nitem->msize; i++) {
612:           PetscViewerASCIIPrintf(view,"%D ",value[i]);
613:         }
614:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
615:       } else if (nitem->dtype == PETSC_BOOL) {
616:         PetscBool value = *(PetscBool*)(((char*)bag) + nitem->offset);
617:         /* some Fortran compilers use -1 as boolean */
618:         if (((int) value) == -1) value = PETSC_TRUE;
619:         /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
620:         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);
621:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,PetscBools[value],nitem->help);
622:       } else if (nitem->dtype == PETSC_ENUM) {
623:         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
624:         PetscInt  i     = 0;
625:         while (nitem->list[i++]) ;
626:         PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
627:       }
628:       nitem = nitem->next;
629:     }
630:   } else if (isbinary) {
631:     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
632:     PetscInt          deprecatedbagsize = 0;
633:     PetscViewerFormat format;
634:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
635:     PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);
636:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
637:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
638:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
639:     while (nitem) {
640:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
641:       dtype = (PetscInt)nitem->dtype;
642:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
643:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
644:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
645:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
646:       /* some Fortran compilers use -1 as boolean */
647:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

649:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
650:       if (dtype == PETSC_ENUM) {
651:         PetscViewerBinaryWriteStringArray(view,(char**)nitem->list);
652:       }
653:       nitem = nitem->next;
654:     }
655:     PetscViewerGetFormat(view,&format);
656:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
657:       MPI_Comm comm;
658:       FILE     *info;
659:       PetscObjectGetComm((PetscObject)view,&comm);
660:       PetscViewerBinaryGetInfoPointer(view,&info);
661:       PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
662:       PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);
663:       PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
664:     }
665:   }
666:   return(0);
667: }

671: /*@C
672:    PetscBagLoad - Loads a bag of values from a binary file

674:    Collective on PetscViewer

676:    Input Parameter:
677: +  viewer - file to load values from
678: -  bag - the bag of values

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

682:    Notes:
683:    Level: beginner

685: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
686:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
687:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

689: @*/
690: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
691: {
693:   PetscBool      isbinary;
694:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
695:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
696:   PetscBagItem   nitem;
697:   MPI_Comm       comm;
698:   PetscMPIInt    flag;

701:   PetscObjectGetComm((PetscObject)view,&comm);
702:   MPI_Comm_compare(comm,bag->bagcomm,&flag);
703:   if (flag != MPI_CONGRUENT && flag != MPI_IDENT) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_NOTSAMECOMM,"Different communicators in the viewer and bag"); \
704:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
705:   if (!isbinary) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");

707:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
708:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
709:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,PETSC_INT);
710:   PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);
711:   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);
712:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
713:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

715:   nitem = bag->bagitems;
716:   for (i=0; i<bagcount; i++) {
717:     PetscViewerBinaryRead(view,&offset,1,PETSC_INT);
718:     /* ignore the offset in the file */
719:     PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);
720:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
721:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
722:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

724:     if (dtype == (PetscInt) PETSC_CHAR) {
725:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);
726:     } else if (dtype == (PetscInt) PETSC_REAL) {
727:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_REAL);
728:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
729:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);
730:     } else if (dtype == (PetscInt) PETSC_INT) {
731:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_INT);
732:     } else if (dtype == (PetscInt) PETSC_BOOL) {
733:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_BOOL);
734:     } else if (dtype == (PetscInt) PETSC_ENUM) {
735:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);
736:       PetscViewerBinaryReadStringArray(view,&list);
737:       /* don't need to save list because it is already registered in the bag */
738:       PetscFree(list);
739:     }
740:     nitem = nitem->next;
741:   }
742:   return(0);
743: }

747: /*@
748:     PetscBagCreate - Create a bag of values

750:   Collective on MPI_Comm

752:   Level: Intermediate

754:   Input Parameters:
755: +  comm - communicator to share bag
756: -  bagsize - size of the C structure holding the values

758:   Output Parameter:
759: .   bag - the bag of values

761:    Notes:
762:       The size of the A struct must be small enough to fit in a PetscInt; by default
763:       PetscInt is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
764:       The warning about casting to a shorter length can be ignored below unless your A struct is too large

766: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
767:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
768:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
769: @*/
770: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
771: {
773:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

776:   PetscInfo1(NULL,"Creating Bag with total size %d\n",(int)totalsize);
777:   PetscMalloc(totalsize,bag);
778:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));

780:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
781:   (*bag)->bagcomm        = comm;
782:   (*bag)->bagprefix      = NULL;
783:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
784:   return(0);
785: }

789: /*@C
790:     PetscBagSetName - Sets the name of a bag of values

792:   Not Collective

794:   Level: Intermediate

796:   Input Parameters:
797: +   bag - the bag of values
798: .   name - the name assigned to the bag
799: -   help - help message for bag

801: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
802:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
803:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
804: @*/

806: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
807: {

811:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
812:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
813:   return(0);
814: }


819: /*@C
820:     PetscBagGetName - Gets the name of a bag of values

822:   Not Collective

824:   Level: Intermediate

826:   Input Parameter:
827: .   bag - the bag of values

829:   Output Parameter:
830: .   name - the name assigned to the bag

832: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
833:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
834:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
835: @*/
836: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
837: {
839:   *name = bag->bagname;
840:   return(0);
841: }

845: /*@C
846:     PetscBagGetData - Gives back the user - access to memory that
847:     should be used for storing user-data-structure

849:   Not Collective

851:   Level: Intermediate

853:   Input Parameter:
854: .   bag - the bag of values

856:   Output Parameter:
857: .   data - pointer to memory that will have user-data-structure

859: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
860:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
861:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
862: @*/
863: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
864: {
866:   *data = bag->structlocation;
867:   return(0);
868: }

872: /*@C
873:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
874:   PetscBag items in the options database.

876:   Logically collective on Bag.

878:   Level: Intermediate

880:   Input Parameters:
881: +   bag - the bag of values
882: -   prefix - the prefix to prepend all Bag item names with.

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

886: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
887:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
888: @*/

890: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
891: {

895:   if (!pre) {
896:     PetscFree(bag->bagprefix);
897:   } else {
898:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
899:     PetscFree(bag->bagprefix);
900:     PetscStrallocpy(pre,&(bag->bagprefix));
901:   }
902:   return(0);
903: }