Actual source code: bag.c

petsc-master 2019-09-18
Report Typos and Errors

  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 Parameter:
 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        = 0;
 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 Parameter:
 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  = 0;
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 Parameter:
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  = 0;
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 Parameter:
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       = 0;
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 Parameter:
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;
257: 
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       = 0;
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 Parameter:
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   = 0;
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 Parameter:
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  = 0;
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 Parameter:
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        = 0;
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 Parameter:
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


443:    Level: beginner

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

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

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

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

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

481:    Logically Collective on PetscBag

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


491:    Level: beginner

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

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

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

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

528: /*@C
529:    PetscBagDestroy - Destroys a bag values

531:    Collective on PetscBag

533:    Input Parameter:
534: .  bag - the bag of values

536:    Level: beginner

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

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

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

562: /*@
563:    PetscBagSetFromOptions - Allows setting options from a bag

565:    Collective on PetscBag

567:    Input Parameter:
568: .  bag - the bag of values

570:    Level: beginner

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

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

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

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

638:    Collective on PetscBag

640:    Input Parameter:
641: +  bag - the bag of values
642: -  viewer - location to view the values

644:    Level: beginner

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

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

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

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

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

762: /*@C
763:    PetscBagLoad - Loads a bag of values from a binary file

765:    Collective on PetscViewer

767:    Input Parameter:
768: +  viewer - file to load values from
769: -  bag - the bag of values

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

774:    Notes:
775:    Level: beginner

777: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
778:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
779:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

781: @*/
782: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
783: {
785:   PetscBool      isbinary;
786:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
787:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
788:   PetscBagItem   nitem;
789:   MPI_Comm       comm;
790:   PetscMPIInt    flag;

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

799:   PetscViewerBinaryRead(view,&classid,1,NULL,PETSC_INT);
800:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
801:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,NULL,PETSC_INT);
802:   PetscViewerBinaryRead(view,&bagcount,1,NULL,PETSC_INT);
803:   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);
804:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
805:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);

807:   nitem = bag->bagitems;
808:   for (i=0; i<bagcount; i++) {
809:     PetscViewerBinaryRead(view,&offset,1,NULL,PETSC_INT);
810:     /* ignore the offset in the file */
811:     PetscViewerBinaryRead(view,&dtype,1,NULL,PETSC_INT);
812:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
813:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);
814:     PetscViewerBinaryRead(view,&msize,1,NULL,PETSC_INT);

816:     if (dtype == (PetscInt) PETSC_CHAR) {
817:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_CHAR);
818:     } else if (dtype == (PetscInt) PETSC_REAL) {
819:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_REAL);
820:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
821:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_SCALAR);
822:     } else if (dtype == (PetscInt) PETSC_INT) {
823:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_INT);
824:     } else if (dtype == (PetscInt) PETSC_BOOL) {
825:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,NULL,PETSC_BOOL);
826:     } else if (dtype == (PetscInt) PETSC_ENUM) {
827:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,NULL,PETSC_ENUM);
828:       PetscViewerBinaryReadStringArray(view,&list);
829:       /* don't need to save list because it is already registered in the bag */
830:       PetscFree(list);
831:     }
832:     nitem = nitem->next;
833:   }
834:   return(0);
835: }

837: /*@C
838:     PetscBagCreate - Create a bag of values

840:   Collective

842:   Level: Intermediate

844:   Input Parameters:
845: +  comm - communicator to share bag
846: -  bagsize - size of the C structure holding the values

848:   Output Parameter:
849: .   bag - the bag of values

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

856: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
857:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
858:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
859: @*/
860: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
861: {
863:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

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

870:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
871:   (*bag)->bagcomm        = comm;
872:   (*bag)->bagprefix      = NULL;
873:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
874:   return(0);
875: }

877: /*@C
878:     PetscBagSetName - Sets the name of a bag of values

880:   Not Collective

882:   Level: Intermediate

884:   Input Parameters:
885: +   bag - the bag of values
886: .   name - the name assigned to the bag
887: -   help - help message for bag

889: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
890:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
891:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
892: @*/

894: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
895: {

899:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
900:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
901:   return(0);
902: }


905: /*@C
906:     PetscBagGetName - Gets the name of a bag of values

908:   Not Collective

910:   Level: Intermediate

912:   Input Parameter:
913: .   bag - the bag of values

915:   Output Parameter:
916: .   name - the name assigned to the bag

918: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
919:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
920:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
921: @*/
922: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
923: {
925:   *name = bag->bagname;
926:   return(0);
927: }

929: /*@C
930:     PetscBagGetData - Gives back the user - access to memory that
931:     should be used for storing user-data-structure

933:   Not Collective

935:   Level: Intermediate

937:   Input Parameter:
938: .   bag - the bag of values

940:   Output Parameter:
941: .   data - pointer to memory that will have user-data-structure

943: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
944:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
945:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
946: @*/
947: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
948: {
950:   *data = bag->structlocation;
951:   return(0);
952: }

954: /*@C
955:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
956:   PetscBag items in the options database.

958:   Logically collective on Bag.

960:   Level: Intermediate

962:   Input Parameters:
963: +   bag - the bag of values
964: -   prefix - the prefix to prepend all Bag item names with.

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

968: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
969:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
970: @*/

972: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
973: {

977:   if (!pre) {
978:     PetscFree(bag->bagprefix);
979:   } else {
980:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
981:     PetscFree(bag->bagprefix);
982:     PetscStrallocpy(pre,&(bag->bagprefix));
983:   }
984:   return(0);
985: }

987: /*@C
988:   PetscBagGetNames - Get the names of all entries in the bag

990:   Not collective

992:   Input Parameters:
993: + bag   - the bag of values
994: - names - array of the correct size to hold names

996:   Output Parameter:
997: . names - array of char pointers for names

999:   Level: intermediate

1001: .seealso: PetscBag, PetscBagGetName(), PetscBagSetName(), PetscBagCreate(), PetscBagGetData()
1002:           PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar(), PetscBagRegisterEnum()
1003: @*/
1004: PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1005: {
1006:   PetscBagItem nitem = bag->bagitems;
1007:   PetscInt     n;

1010:   for (n = 0; nitem; ++n, nitem = nitem->next) {names[n] = nitem->name;}
1011:   return(0);
1012: }