Actual source code: bag.c


  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: {

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

 27: /*@C
 28:    PetscBagRegisterEnum - add an enum value to the bag

 30:    Logically Collective on PetscBag

 32:    Input Parameters:
 33: +  bag - the bag of values
 34: .  addr - location of enum in struct
 35: .  mdefault - the initial value
 36: .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
 37: -  help - longer string with more information about the value

 39:    Level: beginner

 41: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 42:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 43:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

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

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

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

 81: /*@C
 82:    PetscBagRegisterIntArray - add an integer value to the bag

 84:    Logically Collective on PetscBag

 86:    Input Parameters:
 87: +  bag - the bag of values
 88: .  addr - location of integer in struct
 89: .  msize - number of entries in array
 90: .  name - name of the integer array
 91: -  help - longer string with more information about the value

 93:    Level: beginner

 95: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 96:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 97:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

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

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

122:   PetscNew(&item);
123:   item->dtype  = PETSC_INT;
124:   item->offset = ((char*)addr) - ((char*)bag);
125:   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);
126:   item->next  = NULL;
127:   item->msize = msize;
128:   PetscBagRegister_Private(bag,item,name,help);
129:   return(0);
130: }

132: /*@C
133:    PetscBagRegisterRealArray - add an real array to the bag

135:    Logically Collective on PetscBag

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

144:    Level: beginner

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

150: @*/
151: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag,void *addr,PetscInt msize, const char *name, const char *help)
152: {
154:   PetscBagItem   item;
155:   char           nname[PETSC_BAG_NAME_LENGTH+1];
156:   PetscBool      printhelp;
157:   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);
176:   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);
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: {
205:   PetscBagItem   item;
206:   char           nname[PETSC_BAG_NAME_LENGTH+1];
207:   PetscBool      printhelp;

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

219:   PetscNew(&item);
220:   item->dtype  = PETSC_INT;
221:   item->offset = ((char*)addr) - ((char*)bag);
222:   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);
223:   item->next       = NULL;
224:   item->msize      = 1;
225:   *(PetscInt*)addr = mdefault;
226:   PetscBagRegister_Private(bag,item,name,help);
227:   return(0);
228: }

230: /*@C
231:    PetscBagRegisterInt64 - add an integer value to the bag

233:    Logically Collective on PetscBag

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

242:    Level: beginner

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

248: @*/
249: PetscErrorCode PetscBagRegisterInt64(PetscBag bag,void *addr,PetscInt64 mdefault,const char *name,const char *help)
250: {
252:   PetscBagItem   item;
253:   char           nname[PETSC_BAG_NAME_LENGTH+1];
254:   PetscBool      printhelp;
255:   PetscInt       odefault = (PetscInt)mdefault;
256:   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 <%d>: %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);
272:   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);
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: {
302:   PetscBagItem   item;
303:   char           nname[PETSC_BAG_NAME_LENGTH+1];
304:   PetscBool      printhelp;
305:   PetscInt       i,tmp = msize;

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

321:   PetscNew(&item);
322:   item->dtype  = PETSC_BOOL;
323:   item->offset = ((char*)addr) - ((char*)bag);
324:   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);
325:   item->next   = NULL;
326:   item->msize  = msize;
327:   PetscBagRegister_Private(bag,item,name,help);
328:   return(0);
329: }

331: /*@C
332:    PetscBagRegisterString - add a string value to the bag

334:    Logically Collective on PetscBag

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

344:    Level: beginner

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

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

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

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

369:   PetscNew(&item);
370:   item->dtype  = PETSC_CHAR;
371:   item->offset = ((char*)addr) - ((char*)bag);
372:   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);
373:   item->next  = NULL;
374:   item->msize = msize;
375:   if (mdefault != (char*)addr) {
376:     PetscStrncpy((char*)addr,mdefault,msize-1);
377:   }
378:   PetscOptionsGetString(NULL,bag->bagprefix,nname,(char*)addr,msize,NULL);
379:   PetscBagRegister_Private(bag,item,name,help);
380:   return(0);
381: }

383: /*@C
384:    PetscBagRegisterReal - add a real value to the bag

386:    Logically Collective on PetscBag

388:    Input Parameters:
389: +  bag - the bag of values
390: .  addr - location of double in struct
391: .  mdefault - the initial value
392: .  name - name of the variable
393: -  help - longer string with more information about the value

395:    Level: beginner

397: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
398:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
399:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

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

410:   nname[0] = '-';
411:   nname[1] = 0;
412:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
413:   PetscOptionsHasHelp(NULL,&printhelp);
414:   if (printhelp) {
415:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)mdefault,help);
416:   }
417:   PetscOptionsGetReal(NULL,bag->bagprefix,nname,&mdefault,NULL);

419:   PetscNew(&item);
420:   item->dtype  = PETSC_REAL;
421:   item->offset = ((char*)addr) - ((char*)bag);
422:   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);
423:   item->next        = NULL;
424:   item->msize       = 1;
425:   *(PetscReal*)addr = mdefault;
426:   PetscBagRegister_Private(bag,item,name,help);
427:   return(0);
428: }

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

433:    Logically Collective on PetscBag

435:    Input Parameters:
436: +  bag - the bag of values
437: .  addr - location of scalar in struct
438: .  mdefault - the initial value
439: .  name - name of the variable
440: -  help - longer string with more information about the value

442:    Level: beginner

444: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
445:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
446:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

448: @*/
449: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault,const char *name,const char *help)
450: {
452:   PetscBagItem   item;
453:   char           nname[PETSC_BAG_NAME_LENGTH+1];
454:   PetscBool      printhelp;

457:   nname[0] = '-';
458:   nname[1] = 0;
459:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
460:   PetscOptionsHasHelp(NULL,&printhelp);
461:   if (printhelp) {
462:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%g + %gi>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,(double)PetscRealPart(mdefault),(double)PetscImaginaryPart(mdefault),help);
463:   }
464:   PetscOptionsGetScalar(NULL,bag->bagprefix,nname,&mdefault,NULL);

466:   PetscNew(&item);
467:   item->dtype  = PETSC_SCALAR;
468:   item->offset = ((char*)addr) - ((char*)bag);
469:   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);
470:   item->next          = NULL;
471:   item->msize         = 1;
472:   *(PetscScalar*)addr = mdefault;
473:   PetscBagRegister_Private(bag,item,name,help);
474:   return(0);
475: }

477: /*@C
478:    PetscBagRegisterBool - add a logical value to the bag

480:    Logically Collective on PetscBag

482:    Input Parameters:
483: +  bag - the bag of values
484: .  addr - location of logical in struct
485: .  mdefault - the initial value
486: .  name - name of the variable
487: -  help - longer string with more information about the value

489:    Level: beginner

491: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
492:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
493:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

495: @*/
496: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool mdefault,const char *name,const char *help)
497: {
499:   PetscBagItem   item;
500:   char           nname[PETSC_BAG_NAME_LENGTH+1];
501:   PetscBool      printhelp;

504:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
505:   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);
506:   nname[0] = '-';
507:   nname[1] = 0;
508:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
509:   PetscOptionsHasHelp(NULL,&printhelp);
510:   if (printhelp) {
511:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,PetscBools[mdefault],help);
512:   }
513:   PetscOptionsGetBool(NULL,bag->bagprefix,nname,&mdefault,NULL);

515:   PetscNew(&item);
516:   item->dtype  = PETSC_BOOL;
517:   item->offset = ((char*)addr) - ((char*)bag);
518:   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);
519:   item->next        = NULL;
520:   item->msize       = 1;
521:   *(PetscBool*)addr = mdefault;
522:   PetscBagRegister_Private(bag,item,name,help);
523:   return(0);
524: }

526: /*@C
527:    PetscBagDestroy - Destroys a bag values

529:    Collective on PetscBag

531:    Input Parameter:
532: .  bag - the bag of values

534:    Level: beginner

536: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
537:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
538:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

540: @*/
541: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
542: {
544:   PetscBagItem   nitem = (*bag)->bagitems,item;

547:   while (nitem) {
548:     item = nitem->next;
549:     if (nitem->list) {
550:       PetscStrArrayDestroy(&nitem->list);
551:     }
552:     PetscFree(nitem);
553:     nitem = item;
554:   }
555:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
556:   PetscFree(*bag);
557:   return(0);
558: }

560: /*@
561:    PetscBagSetFromOptions - Allows setting options from a bag

563:    Collective on PetscBag

565:    Input Parameter:
566: .  bag - the bag of values

568:    Level: beginner

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

574: @*/
575: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
576: {
578:   PetscBagItem   nitem = bag->bagitems;
579:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
580:   PetscInt       n;

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

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

636:    Collective on PetscBag

638:    Input Parameters:
639: +  bag - the bag of values
640: -  viewer - location to view the values

642:    Level: beginner

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

648: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagLoad(), PetscBagGetData()
649:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
650:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

652: @*/
653: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
654: {
655:   PetscBool      isascii,isbinary;
657:   PetscBagItem   nitem = bag->bagitems;

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

740:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype);
741:       if (dtype == PETSC_ENUM) {
742:         PetscViewerBinaryWriteStringArray(view,(const char* const*)nitem->list);
743:       }
744:       nitem = nitem->next;
745:     }
746:     PetscViewerGetFormat(view,&format);
747:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
748:       MPI_Comm comm;
749:       FILE     *info;
750:       PetscObjectGetComm((PetscObject)view,&comm);
751:       PetscViewerBinaryGetInfoPointer(view,&info);
752:       PetscFPrintf(comm,info,"#--- begin code written by PetscViewerBinary for MATLAB format ---#\n");
753:       PetscFPrintf(comm,info,"#$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);
754:       PetscFPrintf(comm,info,"#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n");
755:     }
756:   }
757:   return(0);
758: }

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

763:   Collective on PetscBag

765:   Input Parameters:
766: + obj   - the object
767: . bobj  - optional other object that provides prefix (if NULL then the prefix in obj is used)
768: - optionname - option to activate viewing

770:   Level: intermediate

772: .seealso: PetscBagCreate(), PetscBag, PetscViewer
773: @*/
774: PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[])
775: {
776:   static PetscBool  incall = PETSC_FALSE;
777:   PetscViewer       viewer;
778:   PetscViewerFormat format;
779:   const char       *prefix, *bprefix = NULL;
780:   PetscBool         flg;
781:   PetscErrorCode    ierr;

784:   if (incall) return(0);
785:   incall = PETSC_TRUE;
786:   if (bobj) {PetscObjectGetOptionsPrefix(bobj, &bprefix);}
787:   prefix = bobj ? bprefix : bag->bagprefix;
788:   PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg);
789:   if (flg) {
790:     PetscViewerPushFormat(viewer, format);
791:     PetscBagView(bag, viewer);
792:     PetscViewerFlush(viewer);
793:     PetscViewerPopFormat(viewer);
794:     PetscViewerDestroy(&viewer);
795:   }
796:   incall = PETSC_FALSE;
797:   return(0);
798: }

800: /*@C
801:    PetscBagLoad - Loads a bag of values from a binary file

803:    Collective on PetscViewer

805:    Input Parameters:
806: +  viewer - file to load values from
807: -  bag - the bag of values

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

812:    Notes:
813:    Level: beginner

815: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
816:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
817:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

819: @*/
820: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
821: {
823:   PetscBool      isbinary;
824:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
825:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
826:   PetscBagItem   nitem;
827:   MPI_Comm       comm;
828:   PetscMPIInt    flag;

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

837:   PetscViewerBinaryRead(view,&classid,1,NULL,PETSC_INT);
838:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
839:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,NULL,PETSC_INT);
840:   PetscViewerBinaryRead(view,&bagcount,1,NULL,PETSC_INT);
841:   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);
842:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
843:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);

845:   nitem = bag->bagitems;
846:   for (i=0; i<bagcount; i++) {
847:     PetscViewerBinaryRead(view,&offset,1,NULL,PETSC_INT);
848:     /* ignore the offset in the file */
849:     PetscViewerBinaryRead(view,&dtype,1,NULL,PETSC_INT);
850:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
851:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);
852:     PetscViewerBinaryRead(view,&msize,1,NULL,PETSC_INT);

854:     if (dtype == (PetscInt) PETSC_CHAR) {
855:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_CHAR);
856:     } else if (dtype == (PetscInt) PETSC_REAL) {
857:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_REAL);
858:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
859:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_SCALAR);
860:     } else if (dtype == (PetscInt) PETSC_INT) {
861:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_INT);
862:     } else if (dtype == (PetscInt) PETSC_BOOL) {
863:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_BOOL);
864:     } else if (dtype == (PetscInt) PETSC_ENUM) {
865:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_ENUM);
866:       PetscViewerBinaryReadStringArray(view,&list);
867:       /* don't need to save list because it is already registered in the bag */
868:       PetscFree(list);
869:     }
870:     nitem = nitem->next;
871:   }
872:   return(0);
873: }

875: /*@C
876:     PetscBagCreate - Create a bag of values

878:   Collective

880:   Level: Intermediate

882:   Input Parameters:
883: +  comm - communicator to share bag
884: -  bagsize - size of the C structure holding the values

886:   Output Parameter:
887: .   bag - the bag of values

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

894: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
895:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
896:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
897: @*/
898: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
899: {
901:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

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

908:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
909:   (*bag)->bagcomm        = comm;
910:   (*bag)->bagprefix      = NULL;
911:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
912:   return(0);
913: }

915: /*@C
916:     PetscBagSetName - Sets the name of a bag of values

918:   Not Collective

920:   Level: Intermediate

922:   Input Parameters:
923: +   bag - the bag of values
924: .   name - the name assigned to the bag
925: -   help - help message for bag

927: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
928:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
929:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
930: @*/

932: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
933: {

937:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
938:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
939:   return(0);
940: }

942: /*@C
943:     PetscBagGetName - Gets the name of a bag of values

945:   Not Collective

947:   Level: Intermediate

949:   Input Parameter:
950: .   bag - the bag of values

952:   Output Parameter:
953: .   name - the name assigned to the bag

955: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
956:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
957:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
958: @*/
959: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
960: {
962:   *name = bag->bagname;
963:   return(0);
964: }

966: /*@C
967:     PetscBagGetData - Gives back the user - access to memory that
968:     should be used for storing user-data-structure

970:   Not Collective

972:   Level: Intermediate

974:   Input Parameter:
975: .   bag - the bag of values

977:   Output Parameter:
978: .   data - pointer to memory that will have user-data-structure

980: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
981:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
982:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
983: @*/
984: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
985: {
987:   *data = bag->structlocation;
988:   return(0);
989: }

991: /*@C
992:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
993:   PetscBag items in the options database.

995:   Logically collective on Bag.

997:   Level: Intermediate

999:   Input Parameters:
1000: +   bag - the bag of values
1001: -   prefix - the prefix to prepend all Bag item names with.

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

1005: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
1006:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
1007: @*/

1009: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1010: {

1014:   if (!pre) {
1015:     PetscFree(bag->bagprefix);
1016:   } else {
1017:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hyphen");
1018:     PetscFree(bag->bagprefix);
1019:     PetscStrallocpy(pre,&(bag->bagprefix));
1020:   }
1021:   return(0);
1022: }

1024: /*@C
1025:   PetscBagGetNames - Get the names of all entries in the bag

1027:   Not collective

1029:   Input Parameters:
1030: + bag   - the bag of values
1031: - names - array of the correct size to hold names

1033:   Output Parameter:
1034: . names - array of char pointers for names

1036:   Level: intermediate

1038: .seealso: PetscBag, PetscBagGetName(), PetscBagSetName(), PetscBagCreate(), PetscBagGetData()
1039:           PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
1040: @*/
1041: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1042: {
1043:   PetscBagItem nitem = bag->bagitems;
1044:   PetscInt     n;

1047:   for (n = 0; nitem; ++n, nitem = nitem->next) {names[n] = nitem->name;}
1048:   return(0);
1049: }