Actual source code: bag.c

  1: #include <petsc/private/petscimpl.h>
  2: #include <petsc/private/bagimpl.h>
  3: #include <petscviewer.h>

  5: /*
  6:       Adds item to the linked list in a bag
  7: */
  8: static PetscErrorCode PetscBagRegister_Private(PetscBag bag,PetscBagItem item,const char *name,const char *help)
  9: {
 10:   PetscStrncpy(item->name,name,PETSC_BAG_NAME_LENGTH-1);
 11:   PetscStrncpy(item->help,help,PETSC_BAG_HELP_LENGTH-1);
 12:   if (bag->bagitems) {
 13:     PetscBagItem nitem = bag->bagitems;

 15:     while (nitem->next) nitem = nitem->next;
 16:     nitem->next = item;
 17:   } else bag->bagitems = item;
 18:   bag->count++;
 19:   return 0;
 20: }

 22: /*@C
 23:    PetscBagRegisterEnum - add an enum value to the bag

 25:    Logically Collective on PetscBag

 27:    Input Parameters:
 28: +  bag - the bag of values
 29: .  addr - location of enum in struct
 30: .  mdefault - the initial value
 31: .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
 32: -  help - longer string with more information about the value

 34:    Level: beginner

 36: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 37:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 38:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

 40: @*/
 41: PetscErrorCode PetscBagRegisterEnum(PetscBag bag,void *addr,const char *const *list,PetscEnum mdefault, const char *name, const char *help)
 42: {
 43:   PetscBagItem   item;
 44:   char           nname[PETSC_BAG_NAME_LENGTH+1];
 45:   PetscBool      printhelp;
 46:   PetscInt       i = 0;

 53:   nname[0] = '-';
 54:   nname[1] = 0;
 55:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
 56:   PetscOptionsHasHelp(NULL,&printhelp);
 57:   if (printhelp) {
 58:     while (list[i++]) ;
 59:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: (%s) %s (choose one of) ",bag->bagprefix ? bag->bagprefix : "",name,list[mdefault],list[i-3],help);
 60:     for (i=0; list[i+2]; i++) (*PetscHelpPrintf)(bag->bagcomm," %s",list[i]);
 61:     (*PetscHelpPrintf)(bag->bagcomm,"\n");
 62:   }
 63:   PetscOptionsGetEnum(NULL,bag->bagprefix,nname,list,&mdefault,NULL);

 65:   PetscNew(&item);
 66:   item->dtype  = PETSC_ENUM;
 67:   item->offset = ((char*)addr) - ((char*)bag);
 69:   item->next  = NULL;
 70:   item->msize = 1;
 71:   PetscStrArrayallocpy(list,(char***)&item->list);
 72:   *(PetscEnum*)addr = mdefault;
 73:   PetscBagRegister_Private(bag,item,name,help);
 74:   return 0;
 75: }

 77: /*@C
 78:    PetscBagRegisterIntArray - add an integer value to the bag

 80:    Logically Collective on PetscBag

 82:    Input Parameters:
 83: +  bag - the bag of values
 84: .  addr - location of integer in struct
 85: .  msize - number of entries in array
 86: .  name - name of the integer array
 87: -  help - longer string with more information about the value

 89:    Level: beginner

 91: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 92:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 93:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

 95: @*/
 96: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag,void *addr,PetscInt msize, const char *name, const char *help)
 97: {
 98:   PetscBagItem   item;
 99:   char           nname[PETSC_BAG_NAME_LENGTH+1];
100:   PetscBool      printhelp;
101:   PetscInt       i,tmp = msize;

107:   nname[0] = '-';
108:   nname[1] = 0;
109:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
110:   PetscOptionsHasHelp(NULL,&printhelp);
111:   if (printhelp) {
112:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix ? bag->bagprefix : "",name);
113:     for (i=0; i<msize; i++) {
114:       (*PetscHelpPrintf)(bag->bagcomm,"%" PetscInt_FMT " ",*((PetscInt*)addr)+i);
115:     }
116:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
117:   }
118:   PetscOptionsGetIntArray(NULL,bag->bagprefix,nname,(PetscInt*)addr,&tmp,NULL);

120:   PetscNew(&item);
121:   item->dtype  = PETSC_INT;
122:   item->offset = ((char*)addr) - ((char*)bag);
124:   item->next  = NULL;
125:   item->msize = msize;
126:   PetscBagRegister_Private(bag,item,name,help);
127:   return 0;
128: }

130: /*@C
131:    PetscBagRegisterRealArray - add an real array to the bag

133:    Logically Collective on PetscBag

135:    Input Parameters:
136: +  bag - the bag of values
137: .  addr - location of real array in struct
138: .  msize - number of entries in array
139: .  name - name of the integer array
140: -  help - longer string with more information about the value

142:    Level: beginner

144: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
145:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
146:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

148: @*/
149: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag,void *addr,PetscInt msize, const char *name, const char *help)
150: {
151:   PetscBagItem   item;
152:   char           nname[PETSC_BAG_NAME_LENGTH+1];
153:   PetscBool      printhelp;
154:   PetscInt       i,tmp = msize;

160:   nname[0] = '-';
161:   nname[1] = 0;
162:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
163:   PetscOptionsHasHelp(NULL,&printhelp);
164:   if (printhelp) {
165:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix ? bag->bagprefix : "",name);
166:     for (i=0; i<msize; i++) {
167:       (*PetscHelpPrintf)(bag->bagcomm,"%g ",(double)*((PetscReal*)addr)+i);
168:     }
169:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
170:   }
171:   PetscOptionsGetRealArray(NULL,bag->bagprefix,nname,(PetscReal*)addr,&tmp,NULL);

173:   PetscNew(&item);
174:   item->dtype  = PETSC_REAL;
175:   item->offset = ((char*)addr) - ((char*)bag);
177:   item->next  = NULL;
178:   item->msize = msize;
179:   PetscBagRegister_Private(bag,item,name,help);
180:   return 0;
181: }

183: /*@C
184:    PetscBagRegisterInt - add an integer value to the bag

186:    Logically Collective on PetscBag

188:    Input Parameters:
189: +  bag - the bag of values
190: .  addr - location of integer in struct
191: .  mdefault - the initial value
192: .  name - name of the integer
193: -  help - longer string with more information about the value

195:    Level: beginner

197: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
198:            PetscBagRegisterInt64(), PetscBagRegisterBool(), PetscBagRegisterScalar()
199:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

201: @*/
202: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault,const char *name,const char *help)
203: {
204:   PetscBagItem   item;
205:   char           nname[PETSC_BAG_NAME_LENGTH+1];
206:   PetscBool      printhelp;

212:   nname[0] = '-';
213:   nname[1] = 0;
214:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
215:   PetscOptionsHasHelp(NULL,&printhelp);
216:   if (printhelp) {
217:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%" PetscInt_FMT ">: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);
218:   }
219:   PetscOptionsGetInt(NULL,bag->bagprefix,nname,&mdefault,NULL);

221:   PetscNew(&item);
222:   item->dtype  = PETSC_INT;
223:   item->offset = ((char*)addr) - ((char*)bag);
225:   item->next       = NULL;
226:   item->msize      = 1;
227:   *(PetscInt*)addr = mdefault;
228:   PetscBagRegister_Private(bag,item,name,help);
229:   return 0;
230: }

232: /*@C
233:    PetscBagRegisterInt64 - add an integer value to the bag

235:    Logically Collective on PetscBag

237:    Input Parameters:
238: +  bag - the bag of values
239: .  addr - location of integer in struct
240: .  mdefault - the initial value
241: .  name - name of the integer
242: -  help - longer string with more information about the value

244:    Level: beginner

246: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
247:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
248:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

250: @*/
251: PetscErrorCode PetscBagRegisterInt64(PetscBag bag,void *addr,PetscInt64 mdefault,const char *name,const char *help)
252: {
253:   PetscBagItem   item;
254:   char           nname[PETSC_BAG_NAME_LENGTH+1];
255:   PetscBool      printhelp;
256:   PetscInt       odefault = (PetscInt)mdefault;
257:   PetscBool      flg;

259:   nname[0] = '-';
260:   nname[1] = 0;
261:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
262:   PetscOptionsHasHelp(NULL,&printhelp);
263:   if (printhelp) {
264:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%" PetscInt_FMT ">: %s \n",bag->bagprefix ? bag->bagprefix : "",name,odefault,help);
265:   }
266:   PetscOptionsGetInt(NULL,bag->bagprefix,nname,&odefault,&flg);
267:   if (flg) mdefault = (PetscInt64)odefault;

269:   PetscNew(&item);
270:   item->dtype  = PETSC_INT;
271:   item->offset = ((char*)addr) - ((char*)bag);
273:   item->next       = NULL;
274:   item->msize      = 1;
275:   *(PetscInt64*)addr = mdefault;
276:   PetscBagRegister_Private(bag,item,name,help);
277:   return 0;
278: }

280: /*@C
281:    PetscBagRegisterBoolArray - add a n logical values to the bag

283:    Logically Collective on PetscBag

285:    Input Parameters:
286: +  bag - the bag of values
287: .  addr - location of boolean array in struct
288: .  msize - number of entries in array
289: .  name - name of the boolean array
290: -  help - longer string with more information about the value

292:    Level: beginner

294: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
295:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
296:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

298: @*/
299: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
300: {
301:   PetscBagItem   item;
302:   char           nname[PETSC_BAG_NAME_LENGTH+1];
303:   PetscBool      printhelp;
304:   PetscInt       i,tmp = msize;

310:   nname[0] = '-';
311:   nname[1] = 0;
312:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
313:   PetscOptionsHasHelp(NULL,&printhelp);
314:   if (printhelp) {
315:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix?bag->bagprefix:"",name);
316:     for (i=0; i<msize; i++) {
317:       (*PetscHelpPrintf)(bag->bagcomm,"%" PetscInt_FMT " ",*((PetscInt*)addr)+i);
318:     }
319:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
320:   }
321:   PetscOptionsGetBoolArray(NULL,bag->bagprefix,nname,(PetscBool*)addr,&tmp,NULL);

323:   PetscNew(&item);
324:   item->dtype  = PETSC_BOOL;
325:   item->offset = ((char*)addr) - ((char*)bag);
327:   item->next   = NULL;
328:   item->msize  = msize;
329:   PetscBagRegister_Private(bag,item,name,help);
330:   return 0;
331: }

333: /*@C
334:    PetscBagRegisterString - add a string value to the bag

336:    Logically Collective on PetscBag

338:    Input Parameters:
339: +  bag - the bag of values
340: .  addr - location of start of string in struct
341: .  msize - length of the string space in the struct
342: .  mdefault - the initial value
343: .  name - name of the string
344: -  help - longer string with more information about the value

346:    Level: beginner

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

350: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
351:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
352:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

354: @*/
355: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault,const char* name,const char* help)
356: {
357:   PetscBagItem item;
358:   char         nname[PETSC_BAG_NAME_LENGTH+1];
359:   PetscBool    printhelp;

366:   nname[0] = '-';
367:   nname[1] = 0;
368:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
369:   PetscOptionsHasHelp(NULL,&printhelp);
370:   if (printhelp) {
371:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,mdefault,help);
372:   }

374:   PetscNew(&item);
375:   item->dtype  = PETSC_CHAR;
376:   item->offset = ((char*)addr) - ((char*)bag);
378:   item->next  = NULL;
379:   item->msize = msize;
380:   if (mdefault != (char*)addr) {
381:     PetscStrncpy((char*)addr,mdefault,msize-1);
382:   }
383:   PetscOptionsGetString(NULL,bag->bagprefix,nname,(char*)addr,msize,NULL);
384:   PetscBagRegister_Private(bag,item,name,help);
385:   return 0;
386: }

388: /*@C
389:    PetscBagRegisterReal - add a real value to the bag

391:    Logically Collective on PetscBag

393:    Input Parameters:
394: +  bag - the bag of values
395: .  addr - location of double in struct
396: .  mdefault - the initial value
397: .  name - name of the variable
398: -  help - longer string with more information about the value

400:    Level: beginner

402: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
403:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
404:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

406: @*/
407: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char *name, const char *help)
408: {
409:   PetscBagItem item;
410:   char         nname[PETSC_BAG_NAME_LENGTH+1];
411:   PetscBool    printhelp;

417:   nname[0] = '-';
418:   nname[1] = 0;
419:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
420:   PetscOptionsHasHelp(NULL,&printhelp);
421:   if (printhelp) {
422:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)mdefault,help);
423:   }
424:   PetscOptionsGetReal(NULL,bag->bagprefix,nname,&mdefault,NULL);

426:   PetscNew(&item);
427:   item->dtype  = PETSC_REAL;
428:   item->offset = ((char*)addr) - ((char*)bag);
430:   item->next        = NULL;
431:   item->msize       = 1;
432:   *(PetscReal*)addr = mdefault;
433:   PetscBagRegister_Private(bag,item,name,help);
434:   return 0;
435: }

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

440:    Logically Collective on PetscBag

442:    Input Parameters:
443: +  bag - the bag of values
444: .  addr - location of scalar in struct
445: .  mdefault - the initial value
446: .  name - name of the variable
447: -  help - longer string with more information about the value

449:    Level: beginner

451: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
452:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
453:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

455: @*/
456: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
457: {
458:   PetscBagItem item;
459:   char         nname[PETSC_BAG_NAME_LENGTH+1];
460:   PetscBool    printhelp;

466:   nname[0] = '-';
467:   nname[1] = 0;
468:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
469:   PetscOptionsHasHelp(NULL,&printhelp);
470:   if (printhelp) {
471:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g + %gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)PetscRealPart(mdefault),(double)PetscImaginaryPart(mdefault),help);
472:   }
473:   PetscOptionsGetScalar(NULL,bag->bagprefix,nname,&mdefault,NULL);

475:   PetscNew(&item);
476:   item->dtype  = PETSC_SCALAR;
477:   item->offset = ((char*)addr) - ((char*)bag);
479:   item->next          = NULL;
480:   item->msize         = 1;
481:   *(PetscScalar*)addr = mdefault;
482:   PetscBagRegister_Private(bag,item,name,help);
483:   return 0;
484: }

486: /*@C
487:    PetscBagRegisterBool - add a logical value to the bag

489:    Logically Collective on PetscBag

491:    Input Parameters:
492: +  bag - the bag of values
493: .  addr - location of logical in struct
494: .  mdefault - the initial value
495: .  name - name of the variable
496: -  help - longer string with more information about the value

498:    Level: beginner

500: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
501:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
502:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

504: @*/
505: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
506: {
507:   PetscBagItem item;
508:   char         nname[PETSC_BAG_NAME_LENGTH+1];
509:   PetscBool    printhelp;

515:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
517:   nname[0] = '-';
518:   nname[1] = 0;
519:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
520:   PetscOptionsHasHelp(NULL,&printhelp);
521:   if (printhelp) {
522:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);
523:   }
524:   PetscOptionsGetBool(NULL,bag->bagprefix,nname,&mdefault,NULL);

526:   PetscNew(&item);
527:   item->dtype  = PETSC_BOOL;
528:   item->offset = ((char*)addr) - ((char*)bag);
530:   item->next        = NULL;
531:   item->msize       = 1;
532:   *(PetscBool*)addr = mdefault;
533:   PetscBagRegister_Private(bag,item,name,help);
534:   return 0;
535: }

537: /*@C
538:    PetscBagDestroy - Destroys a bag values

540:    Collective on PetscBag

542:    Input Parameter:
543: .  bag - the bag of values

545:    Level: beginner

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

551: @*/
552: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
553: {
554:   PetscBagItem nitem;

556:   if (!*bag) return 0;
558:   nitem = (*bag)->bagitems;
559:   while (nitem) {
560:     PetscBagItem item = nitem->next;

562:     if (nitem->list) PetscStrArrayDestroy(&nitem->list);
563:     PetscFree(nitem);
564:     nitem = item;
565:   }
566:   if ((*bag)->bagprefix) PetscFree((*bag)->bagprefix);
567:   PetscFree(*bag);
568:   return 0;
569: }

571: /*@
572:    PetscBagSetFromOptions - Allows setting options from a bag

574:    Collective on PetscBag

576:    Input Parameter:
577: .  bag - the bag of values

579:    Level: beginner

581: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
582:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
583:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagView(), PetscBagRegisterEnum()

585: @*/
586: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
587: {
589:   PetscBagItem   nitem = bag->bagitems;
590:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
591:   PetscInt       n;

594:   PetscStrncpy(helpname,bag->bagname,sizeof(helpname));
595:   PetscStrlcat(helpname," ",sizeof(helpname));
596:   PetscStrlcat(helpname,bag->baghelp,sizeof(helpname));
597:   PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,NULL);
598:   while (nitem) {
599:     name[0] = '-';
600:     name[1] = 0;
601:     PetscStrlcat(name,nitem->name,sizeof(name));
602:     if (nitem->dtype == PETSC_CHAR) {   /* special handling for fortran required? [due to space padding vs null termination] */
603:       char *value = (char*)(((char*)bag) + nitem->offset);
604:       PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,NULL);
605:     } else if (nitem->dtype == PETSC_REAL) {
606:       PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
607:       if (nitem->msize == 1) {
608:         PetscOptionsReal(name,nitem->help,"",*value,value,NULL);
609:       } else {
610:         n    = nitem->msize;
611:         PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);
612:       }
613:     } else if (nitem->dtype == PETSC_SCALAR) {
614:       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
615:       PetscOptionsScalar(name,nitem->help,"",*value,value,NULL);
616:     } else if (nitem->dtype == PETSC_INT) {
617:       PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
618:       if (nitem->msize == 1) {
619:         PetscOptionsInt(name,nitem->help,"",*value,value,NULL);
620:       } else {
621:         n    = nitem->msize;
622:         PetscOptionsIntArray(name,nitem->help,"",value,&n,NULL);
623:       }
624:     } else if (nitem->dtype == PETSC_ENUM) {
625:       PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
626:       PetscInt  i      = 0;
627:       while (nitem->list[i++]) ;
628:       PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,NULL);
629:     } else if (nitem->dtype == PETSC_BOOL) {
630:       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
631:       if (nitem->msize == 1) {
632:         PetscOptionsBool(name,nitem->help,"",*value,value,NULL);
633:       } else {
634:         n = nitem->msize;
635:         PetscOptionsBoolArray(name,nitem->help,"",value,&n,NULL);
636:       }
637:     }
638:     nitem = nitem->next;
639:   }
640:   PetscOptionsEnd();
641:   return 0;
642: }

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

647:    Collective on PetscBag

649:    Input Parameters:
650: +  bag - the bag of values
651: -  viewer - location to view the values

653:    Level: beginner

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

659: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
660:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
661:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

663: @*/
664: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
665: {
666:   PetscBool    isascii,isbinary;
667:   PetscBagItem nitem = bag->bagitems;

671:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
672:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
673:   if (isascii) {
674:     if (bag->bagprefix) {
675:       PetscViewerASCIIPrintf(view,"PetscBag Object:  %s (%s) %s\n",bag->bagname,bag->bagprefix,bag->baghelp);
676:     } else {
677:       PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
678:     }
679:     while (nitem) {
680:       if (nitem->dtype == PETSC_CHAR) {
681:         char *value = (char*)(((char*)bag) + nitem->offset);
682:         char tmp    = value[nitem->msize-1]; /* special handling for fortran chars wihout null terminator */
683:         value[nitem->msize-1] =0;
684:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
685:         value[nitem->msize-1] = tmp;
686:       } else if (nitem->dtype == PETSC_REAL) {
687:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
688:         PetscInt  i;
689:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
690:         for (i=0; i<nitem->msize; i++) {
691:           PetscViewerASCIIPrintf(view,"%g ",(double)value[i]);
692:         }
693:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
694:       } else if (nitem->dtype == PETSC_SCALAR) {
695:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
696: #if defined(PETSC_USE_COMPLEX)
697:         if ((double)PetscImaginaryPart(value)) {
698:           PetscViewerASCIIPrintf(view,"  %s = %g + %gi; %s\n",nitem->name,(double)PetscRealPart(value),(double)PetscImaginaryPart(value),nitem->help);
699:         } else {
700:           PetscViewerASCIIPrintf(view,"  %s = %g; %s\n",nitem->name,(double)PetscRealPart(value),nitem->help);
701:         }
702: #else
703:         PetscViewerASCIIPrintf(view,"  %s = %g; %s\n",nitem->name,(double)value,nitem->help);
704: #endif
705:       } else if (nitem->dtype == PETSC_INT) {
706:         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
707:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
708:         for (i=0; i<nitem->msize; i++) {
709:           PetscViewerASCIIPrintf(view,"%" PetscInt_FMT " ",value[i]);
710:         }
711:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
712:       } else if (nitem->dtype == PETSC_BOOL) {
713:         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
714:         PetscInt  i;
715:          /* some Fortran compilers use -1 as boolean */
716:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
717:         for (i=0; i<nitem->msize; i++) {
718:           if (((int) value[i]) == -1) value[i] = PETSC_TRUE;
719:           /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
721:           PetscViewerASCIIPrintf(view," %s",PetscBools[value[i]]);
722:         }
723:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
724:       } else if (nitem->dtype == PETSC_ENUM) {
725:         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
726:         PetscInt  i     = 0;
727:         while (nitem->list[i++]) ;
728:         PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
729:       }
730:       nitem = nitem->next;
731:     }
732:   } else if (isbinary) {
733:     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
734:     PetscInt          deprecatedbagsize = 0;
735:     PetscViewerFormat format;
736:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT);
737:     PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT);
738:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT);
739:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
740:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
741:     while (nitem) {
742:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT);
743:       dtype = (PetscInt)nitem->dtype;
744:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT);
745:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
746:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
747:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT);
748:       /* some Fortran compilers use -1 as boolean */
749:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

751:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype);
752:       if (dtype == PETSC_ENUM) {
753:         PetscViewerBinaryWriteStringArray(view,(const char* const*)nitem->list);
754:       }
755:       nitem = nitem->next;
756:     }
757:     PetscViewerGetFormat(view,&format);
758:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
759:       MPI_Comm comm;
760:       FILE     *info;
761:       PetscObjectGetComm((PetscObject)view,&comm);
762:       PetscViewerBinaryGetInfoPointer(view,&info);
763:       PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
764:       PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);
765:       PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
766:     }
767:   }
768:   return 0;
769: }

771: /*@C
772:   PetscBagViewFromOptions - Processes command line options to determine if/how a PetscBag is to be viewed.

774:   Collective on PetscBag

776:   Input Parameters:
777: + obj   - the object
778: . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
779: - optionname - option to activate viewing

781:   Level: intermediate

783: .seealso: PetscBagCreate(), PetscBag, PetscViewer
784: @*/
785: PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[])
786: {
787:   static PetscBool  incall = PETSC_FALSE;
788:   PetscViewer       viewer;
789:   PetscViewerFormat format;
790:   const char       *prefix, *bprefix = NULL;
791:   PetscBool         flg;

793:   if (incall) return 0;
794:   incall = PETSC_TRUE;
796:   if (bobj) PetscObjectGetOptionsPrefix(bobj, &bprefix);
797:   prefix = bobj ? bprefix : bag->bagprefix;
798:   PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg);
799:   if (flg) {
800:     PetscViewerPushFormat(viewer, format);
801:     PetscBagView(bag, viewer);
802:     PetscViewerFlush(viewer);
803:     PetscViewerPopFormat(viewer);
804:     PetscViewerDestroy(&viewer);
805:   }
806:   incall = PETSC_FALSE;
807:   return 0;
808: }

810: /*@C
811:    PetscBagLoad - Loads a bag of values from a binary file

813:    Collective on PetscViewer

815:    Input Parameters:
816: +  viewer - file to load values from
817: -  bag - the bag of values

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

822:    Notes:
823:    Level: beginner

825: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
826:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
827:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

829: @*/
830: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
831: {
832:   PetscBool    isbinary;
833:   PetscInt     classid,bagcount,dtype,msize,offset,deprecatedbagsize;
834:   char         name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
835:   PetscBagItem nitem;
836:   MPI_Comm     comm;
837:   PetscMPIInt  flag;

841:   PetscObjectGetComm((PetscObject)view,&comm);
842:   MPI_Comm_compare(comm,bag->bagcomm,&flag);
844:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);

847:   PetscViewerBinaryRead(view,&classid,1,NULL,PETSC_INT);
849:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,NULL,PETSC_INT);
850:   PetscViewerBinaryRead(view,&bagcount,1,NULL,PETSC_INT);
852:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
853:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);

855:   nitem = bag->bagitems;
856:   for (PetscInt i=0; i<bagcount; i++) {
857:     PetscViewerBinaryRead(view,&offset,1,NULL,PETSC_INT);
858:     /* ignore the offset in the file */
859:     PetscViewerBinaryRead(view,&dtype,1,NULL,PETSC_INT);
860:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
861:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);
862:     PetscViewerBinaryRead(view,&msize,1,NULL,PETSC_INT);

864:     if (dtype == (PetscInt) PETSC_CHAR) {
865:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_CHAR);
866:     } else if (dtype == (PetscInt) PETSC_REAL) {
867:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_REAL);
868:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
869:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_SCALAR);
870:     } else if (dtype == (PetscInt) PETSC_INT) {
871:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_INT);
872:     } else if (dtype == (PetscInt) PETSC_BOOL) {
873:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_BOOL);
874:     } else if (dtype == (PetscInt) PETSC_ENUM) {
875:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_ENUM);
876:       PetscViewerBinaryReadStringArray(view,&list);
877:       /* don't need to save list because it is already registered in the bag */
878:       PetscFree(list);
879:     }
880:     nitem = nitem->next;
881:   }
882:   return 0;
883: }

885: /*@C
886:     PetscBagCreate - Create a bag of values

888:   Collective

890:   Level: Intermediate

892:   Input Parameters:
893: +  comm - communicator to share bag
894: -  bagsize - size of the C structure holding the values

896:   Output Parameter:
897: .   bag - the bag of values

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

904: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
905:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
906:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
907: @*/
908: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
909: {
910:   const size_t totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

913:   PetscInfo(NULL,"Creating Bag with total size %d\n",(int)totalsize);
914:   PetscCalloc(totalsize,bag);

916:   (*bag)->bagsize        = totalsize;
917:   (*bag)->bagcomm        = comm;
918:   (*bag)->bagprefix      = NULL;
919:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
920:   return 0;
921: }

923: /*@C
924:     PetscBagSetName - Sets the name of a bag of values

926:   Not Collective

928:   Level: Intermediate

930:   Input Parameters:
931: +   bag - the bag of values
932: .   name - the name assigned to the bag
933: -   help - help message for bag

935: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
936:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
937:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
938: @*/

940: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
941: {
945:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
946:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
947:   return 0;
948: }

950: /*@C
951:     PetscBagGetName - Gets the name of a bag of values

953:   Not Collective

955:   Level: Intermediate

957:   Input Parameter:
958: .   bag - the bag of values

960:   Output Parameter:
961: .   name - the name assigned to the bag

963: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
964:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
965:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
966: @*/
967: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
968: {
971:   *name = bag->bagname;
972:   return 0;
973: }

975: /*@C
976:     PetscBagGetData - Gives back the user - access to memory that
977:     should be used for storing user-data-structure

979:   Not Collective

981:   Level: Intermediate

983:   Input Parameter:
984: .   bag - the bag of values

986:   Output Parameter:
987: .   data - pointer to memory that will have user-data-structure

989: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
990:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
991:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
992: @*/
993: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
994: {
997:   *data = bag->structlocation;
998:   return 0;
999: }

1001: /*@C
1002:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
1003:   PetscBag items in the options database.

1005:   Logically collective on Bag.

1007:   Level: Intermediate

1009:   Input Parameters:
1010: +   bag - the bag of values
1011: -   prefix - the prefix to prepend all Bag item names with.

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

1015: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
1016:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
1017: @*/

1019: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1020: {
1022:   if (pre) {
1025:     PetscFree(bag->bagprefix);
1026:     PetscStrallocpy(pre,&(bag->bagprefix));
1027:   } else PetscFree(bag->bagprefix);
1028:   return 0;
1029: }

1031: /*@C
1032:   PetscBagGetNames - Get the names of all entries in the bag

1034:   Not collective

1036:   Input Parameters:
1037: + bag   - the bag of values
1038: - names - array of the correct size to hold names

1040:   Output Parameter:
1041: . names - array of char pointers for names

1043:   Level: intermediate

1045: .seealso: PetscBag, PetscBagGetName(), PetscBagSetName(), PetscBagCreate(), PetscBagGetData()
1046:           PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
1047: @*/
1048: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1049: {
1050:   PetscBagItem nitem = bag->bagitems;

1054:   for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
1055:   return 0;
1056: }