Actual source code: bag.c

petsc-3.5.2 2014-09-08
Report Typos and Errors
  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(&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(&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 ",(double)*((PetscReal*)addr)+i);
178:     }
179:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
180:   }
181:   PetscOptionsGetRealArray(bag->bagprefix,nname,(PetscReal*)addr,&tmp,NULL);

183:   PetscNew(&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(&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:    PetscBagRegisterBoolArray - add a n logical values to the bag

247:    Logically Collective on PetscBag

249:    Input Parameter:
250: +  bag - the bag of values
251: .  addr - location of boolean array in struct
252: .  msize - number of entries in array
253: .  name - name of the boolean array
254: -  help - longer string with more information about the value

256:    Level: beginner

258: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
259:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
260:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

262: @*/
263: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
264: {
266:   PetscBagItem   item;
267:   char           nname[PETSC_BAG_NAME_LENGTH+1];
268:   PetscBool      printhelp;
269:   PetscInt       i,tmp = msize;

272:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
273:   nname[0] = '-';
274:   nname[1] = 0;
275:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
276:   PetscOptionsHasName(NULL,"-help",&printhelp);
277:   if (printhelp) {
278:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix?bag->bagprefix:"",name);
279:     for (i=0; i<msize; i++) {
280:       (*PetscHelpPrintf)(bag->bagcomm,"%D ",*((PetscInt*)addr)+i);
281:     }
282:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
283:   }
284:   PetscOptionsGetBoolArray(bag->bagprefix,nname,(PetscBool*)addr,&tmp,NULL);

286:   PetscNew(&item);
287:   item->dtype  = PETSC_BOOL;
288:   item->offset = ((char*)addr) - ((char*)bag);
289:   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);
290:   item->next   = 0;
291:   item->msize  = msize;
292:   PetscBagRegister_Private(bag,item,name,help);
293:   return(0);
294: }

298: /*@C
299:    PetscBagRegisterString - add a string value to the bag

301:    Logically Collective on PetscBag

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

311:    Level: beginner

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

315: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
316:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
317:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

319: @*/
320: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault,const char* name,const char* help)
321: {
323:   PetscBagItem   item;
324:   char           nname[PETSC_BAG_NAME_LENGTH+1];
325:   PetscBool      printhelp;

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

336:   PetscNew(&item);
337:   item->dtype  = PETSC_CHAR;
338:   item->offset = ((char*)addr) - ((char*)bag);
339:   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);
340:   item->next  = 0;
341:   item->msize = msize;
342:   if (mdefault != (char*)addr) {
343:     PetscStrncpy((char*)addr,mdefault,msize-1);
344:   }
345:   PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,NULL);
346:   PetscBagRegister_Private(bag,item,name,help);
347:   return(0);
348: }

352: /*@C
353:    PetscBagRegisterReal - add a real value to the bag

355:    Logically Collective on PetscBag

357:    Input Parameter:
358: +  bag - the bag of values
359: .  addr - location of double in struct
360: .  mdefault - the initial value
361: .  name - name of the variable
362: -  help - longer string with more information about the value

364:    Level: beginner

366: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
367:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
368:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

370: @*/
371: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char *name, const char *help)
372: {
374:   PetscBagItem   item;
375:   char           nname[PETSC_BAG_NAME_LENGTH+1];
376:   PetscBool      printhelp;

379:   nname[0] = '-';
380:   nname[1] = 0;
381:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
382:   PetscOptionsHasName(NULL,"-help",&printhelp);
383:   if (printhelp) {
384:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)mdefault,help);
385:   }
386:   PetscOptionsGetReal(bag->bagprefix,nname,&mdefault,NULL);

388:   PetscNew(&item);
389:   item->dtype  = PETSC_REAL;
390:   item->offset = ((char*)addr) - ((char*)bag);
391:   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);
392:   item->next        = 0;
393:   item->msize       = 1;
394:   *(PetscReal*)addr = mdefault;
395:   PetscBagRegister_Private(bag,item,name,help);
396:   return(0);
397: }

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

404:    Logically Collective on PetscBag

406:    Input Parameter:
407: +  bag - the bag of values
408: .  addr - location of scalar in struct
409: .  mdefault - the initial value
410: .  name - name of the variable
411: -  help - longer string with more information about the value


414:    Level: beginner

416: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
417:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
418:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

420: @*/
421: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
422: {
424:   PetscBagItem   item;
425:   char           nname[PETSC_BAG_NAME_LENGTH+1];
426:   PetscBool      printhelp;

429:   nname[0] = '-';
430:   nname[1] = 0;
431:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
432:   PetscOptionsHasName(NULL,"-help",&printhelp);
433:   if (printhelp) {
434:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g + %gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)PetscRealPart(mdefault),(double)PetscImaginaryPart(mdefault),help);
435:   }
436:   PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,NULL);

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

451: /*@C
452:    PetscBagRegisterBool - add a logical value to the bag

454:    Logically Collective on PetscBag

456:    Input Parameter:
457: +  bag - the bag of values
458: .  addr - location of logical in struct
459: .  mdefault - the initial value
460: .  name - name of the variable
461: -  help - longer string with more information about the value


464:    Level: beginner

466: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
467:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
468:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

470: @*/
471: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
472: {
474:   PetscBagItem   item;
475:   char           nname[PETSC_BAG_NAME_LENGTH+1];
476:   PetscBool      printhelp;

479:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
480:   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);
481:   nname[0] = '-';
482:   nname[1] = 0;
483:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
484:   PetscOptionsHasName(NULL,"-help",&printhelp);
485:   if (printhelp) {
486:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);
487:   }
488:   PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,NULL);

490:   PetscNew(&item);
491:   item->dtype  = PETSC_BOOL;
492:   item->offset = ((char*)addr) - ((char*)bag);
493:   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);
494:   item->next        = 0;
495:   item->msize       = 1;
496:   *(PetscBool*)addr = mdefault;
497:   PetscBagRegister_Private(bag,item,name,help);
498:   return(0);
499: }

503: /*@C
504:    PetscBagDestroy - Destroys a bag values

506:    Collective on PetscBag

508:    Input Parameter:
509: .  bag - the bag of values

511:    Level: beginner

513: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
514:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
515:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

517: @*/
518: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
519: {
521:   PetscBagItem   nitem = (*bag)->bagitems,item;

524:   while (nitem) {
525:     item = nitem->next;
526:     if (nitem->list) {
527:       PetscStrArrayDestroy(&nitem->list);
528:     }
529:     PetscFree(nitem);
530:     nitem = item;
531:   }
532:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
533:   PetscFree(*bag);
534:   return(0);
535: }

539: /*@
540:    PetscBagSetFromOptions - Allows setting options from a bag

542:    Collective on PetscBag

544:    Input Parameter:
545: .  bag - the bag of values

547:    Level: beginner

549: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
550:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
551:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()

553: @*/
554: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
555: {
557:   PetscBagItem   nitem = bag->bagitems;
558:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
559:   PetscInt       n;

562:   PetscStrcpy(helpname,bag->bagname);
563:   PetscStrcat(helpname," ");
564:   PetscStrcat(helpname,bag->baghelp);
565:   PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,0);
566:   while (nitem) {
567:     name[0] = '-';
568:     name[1] = 0;
569:     PetscStrcat(name,nitem->name);
570:     if (nitem->dtype == PETSC_CHAR) {   /* special handling for fortran required? [due to space padding vs null termination] */
571:       char *value = (char*)(((char*)bag) + nitem->offset);
572:       PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,NULL);
573:     } else if (nitem->dtype == PETSC_REAL) {
574:       PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
575:       if (nitem->msize == 1) {
576:         PetscOptionsReal(name,nitem->help,"",*value,value,NULL);
577:       } else {
578:         n    = nitem->msize;
579:         PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);
580:       }
581:     } else if (nitem->dtype == PETSC_SCALAR) {
582:       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
583:       PetscOptionsScalar(name,nitem->help,"",*value,value,NULL);
584:     } else if (nitem->dtype == PETSC_INT) {
585:       PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
586:       if (nitem->msize == 1) {
587:         PetscOptionsInt(name,nitem->help,"",*value,value,NULL);
588:       } else {
589:         n    = nitem->msize;
590:         PetscOptionsIntArray(name,nitem->help,"",value,&n,NULL);
591:       }
592:     } else if (nitem->dtype == PETSC_ENUM) {
593:       PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
594:       PetscInt  i      = 0;
595:       while (nitem->list[i++]) ;
596:       PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,NULL);
597:     } else if (nitem->dtype == PETSC_BOOL) {
598:       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
599:       if (nitem->msize == 1) {
600:         PetscOptionsBool(name,nitem->help,"",*value,value,NULL);
601:       } else {
602:         n = nitem->msize;
603:         PetscOptionsBoolArray(name,nitem->help,"",value,&n,NULL);
604:       }
605:     }
606:     nitem = nitem->next;
607:   }
608:   PetscOptionsEnd();
609:   return(0);
610: }

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

617:    Collective on PetscBag

619:    Input Parameter:
620: +  bag - the bag of values
621: -  viewer - location to view the values

623:    Level: beginner

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

629: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
630:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
631:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

633: @*/
634: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
635: {
636:   PetscBool      isascii,isbinary;
638:   PetscBagItem   nitem = bag->bagitems;

641:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
642:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
643:   if (isascii) {
644:     if (bag->bagprefix) {
645:       PetscViewerASCIIPrintf(view,"PetscBag Object:  %s (%s) %s\n",bag->bagname,bag->bagprefix,bag->baghelp);
646:     } else {
647:       PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
648:     }
649:     while (nitem) {
650:       if (nitem->dtype == PETSC_CHAR) {
651:         char *value = (char*)(((char*)bag) + nitem->offset);
652:         char tmp    = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
653:         value[nitem->msize-1] =0;
654:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
655:         value[nitem->msize-1] = tmp;
656:       } else if (nitem->dtype == PETSC_REAL) {
657:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
658:         PetscInt  i;
659:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
660:         for (i=0; i<nitem->msize; i++) {
661:           PetscViewerASCIIPrintf(view,"%g ",(double)value[i]);
662:         }
663:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
664:       } else if (nitem->dtype == PETSC_SCALAR) {
665:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
666: #if defined(PETSC_USE_COMPLEX)
667:         PetscViewerASCIIPrintf(view,"  %s = %g + %gi; %s\n",nitem->name,(double)PetscRealPart(value),(double)PetscImaginaryPart(value),nitem->help);
668: #else
669:         PetscViewerASCIIPrintf(view,"  %s = %g; %s\n",nitem->name,(double)value,nitem->help);
670: #endif
671:       } else if (nitem->dtype == PETSC_INT) {
672:         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
673:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
674:         for (i=0; i<nitem->msize; i++) {
675:           PetscViewerASCIIPrintf(view,"%D ",value[i]);
676:         }
677:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
678:       } else if (nitem->dtype == PETSC_BOOL) {
679:         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
680:         PetscInt  i;
681:          /* some Fortran compilers use -1 as boolean */
682:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
683:         for (i=0; i<nitem->msize; i++) {
684:           if (((int) value[i]) == -1) value[i] = PETSC_TRUE;
685:           /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
686:           if (value[i] != PETSC_FALSE && value[i] != PETSC_TRUE) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Boolean value for %s %s is corrupt; integer value %d",nitem->name,nitem->help,value);
687:           PetscViewerASCIIPrintf(view," %s",PetscBools[value[i]]);
688:         }
689:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
690:       } else if (nitem->dtype == PETSC_ENUM) {
691:         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
692:         PetscInt  i     = 0;
693:         while (nitem->list[i++]) ;
694:         PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
695:       }
696:       nitem = nitem->next;
697:     }
698:   } else if (isbinary) {
699:     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
700:     PetscInt          deprecatedbagsize = 0;
701:     PetscViewerFormat format;
702:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
703:     PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);
704:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
705:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
706:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
707:     while (nitem) {
708:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
709:       dtype = (PetscInt)nitem->dtype;
710:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
711:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
712:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
713:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
714:       /* some Fortran compilers use -1 as boolean */
715:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

717:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
718:       if (dtype == PETSC_ENUM) {
719:         PetscViewerBinaryWriteStringArray(view,(char**)nitem->list);
720:       }
721:       nitem = nitem->next;
722:     }
723:     PetscViewerGetFormat(view,&format);
724:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
725:       MPI_Comm comm;
726:       FILE     *info;
727:       PetscObjectGetComm((PetscObject)view,&comm);
728:       PetscViewerBinaryGetInfoPointer(view,&info);
729:       PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
730:       PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);
731:       PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
732:     }
733:   }
734:   return(0);
735: }

739: /*@C
740:    PetscBagLoad - Loads a bag of values from a binary file

742:    Collective on PetscViewer

744:    Input Parameter:
745: +  viewer - file to load values from
746: -  bag - the bag of values

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

750:    Notes:
751:    Level: beginner

753: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
754:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
755:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

757: @*/
758: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
759: {
761:   PetscBool      isbinary;
762:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
763:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
764:   PetscBagItem   nitem;
765:   MPI_Comm       comm;
766:   PetscMPIInt    flag;

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

775:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
776:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
777:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,PETSC_INT);
778:   PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);
779:   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);
780:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
781:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

783:   nitem = bag->bagitems;
784:   for (i=0; i<bagcount; i++) {
785:     PetscViewerBinaryRead(view,&offset,1,PETSC_INT);
786:     /* ignore the offset in the file */
787:     PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);
788:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
789:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
790:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

792:     if (dtype == (PetscInt) PETSC_CHAR) {
793:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);
794:     } else if (dtype == (PetscInt) PETSC_REAL) {
795:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_REAL);
796:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
797:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);
798:     } else if (dtype == (PetscInt) PETSC_INT) {
799:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_INT);
800:     } else if (dtype == (PetscInt) PETSC_BOOL) {
801:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_BOOL);
802:     } else if (dtype == (PetscInt) PETSC_ENUM) {
803:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);
804:       PetscViewerBinaryReadStringArray(view,&list);
805:       /* don't need to save list because it is already registered in the bag */
806:       PetscFree(list);
807:     }
808:     nitem = nitem->next;
809:   }
810:   return(0);
811: }

815: /*@
816:     PetscBagCreate - Create a bag of values

818:   Collective on MPI_Comm

820:   Level: Intermediate

822:   Input Parameters:
823: +  comm - communicator to share bag
824: -  bagsize - size of the C structure holding the values

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

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

834: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
835:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
836:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
837: @*/
838: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
839: {
841:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

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

848:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
849:   (*bag)->bagcomm        = comm;
850:   (*bag)->bagprefix      = NULL;
851:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
852:   return(0);
853: }

857: /*@C
858:     PetscBagSetName - Sets the name of a bag of values

860:   Not Collective

862:   Level: Intermediate

864:   Input Parameters:
865: +   bag - the bag of values
866: .   name - the name assigned to the bag
867: -   help - help message for bag

869: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
870:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
871:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
872: @*/

874: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
875: {

879:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
880:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
881:   return(0);
882: }


887: /*@C
888:     PetscBagGetName - Gets the name of a bag of values

890:   Not Collective

892:   Level: Intermediate

894:   Input Parameter:
895: .   bag - the bag of values

897:   Output Parameter:
898: .   name - the name assigned to the bag

900: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
901:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
902:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
903: @*/
904: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
905: {
907:   *name = bag->bagname;
908:   return(0);
909: }

913: /*@C
914:     PetscBagGetData - Gives back the user - access to memory that
915:     should be used for storing user-data-structure

917:   Not Collective

919:   Level: Intermediate

921:   Input Parameter:
922: .   bag - the bag of values

924:   Output Parameter:
925: .   data - pointer to memory that will have user-data-structure

927: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
928:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
929:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
930: @*/
931: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
932: {
934:   *data = bag->structlocation;
935:   return(0);
936: }

940: /*@C
941:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
942:   PetscBag items in the options database.

944:   Logically collective on Bag.

946:   Level: Intermediate

948:   Input Parameters:
949: +   bag - the bag of values
950: -   prefix - the prefix to prepend all Bag item names with.

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

954: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
955:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
956: @*/

958: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
959: {

963:   if (!pre) {
964:     PetscFree(bag->bagprefix);
965:   } else {
966:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
967:     PetscFree(bag->bagprefix);
968:     PetscStrallocpy(pre,&(bag->bagprefix));
969:   }
970:   return(0);
971: }

975: /*@C
976:   PetscBagGetNames - Get the names of all entries in the bag

978:   Not collective

980:   Input Parameters:
981: + bag   - the bag of values
982: - names - array of the correct size to hold names

984:   Output Parameter:
985: . names - array of char pointers for names

987:   Level: intermediate

989: .seealso: PetscBag, PetscBagGetName(), PetscBagSetName(), PetscBagCreate(), PetscBagGetData()
990:           PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
991: @*/
992: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
993: {
994:   PetscBagItem nitem = bag->bagitems;
995:   PetscInt     n;

998:   for (n = 0; nitem; ++n, nitem = nitem->next) {names[n] = nitem->name;}
999:   return(0);
1000: }