Actual source code: bag.c

petsc-3.11.4 2019-09-28
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:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
110:   nname[0] = '-';
111:   nname[1] = 0;
112:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
113:   PetscOptionsHasHelp(NULL,&printhelp);
114:   if (printhelp) {
115:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix ? bag->bagprefix : "",name);
116:     for (i=0; i<msize; i++) {
117:       (*PetscHelpPrintf)(bag->bagcomm,"%D ",*((PetscInt*)addr)+i);
118:     }
119:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
120:   }
121:   PetscOptionsGetIntArray(NULL,bag->bagprefix,nname,(PetscInt*)addr,&tmp,NULL);

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

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

136:    Logically Collective on PetscBag

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

145:    Level: beginner

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

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

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

175:   PetscNew(&item);
176:   item->dtype  = PETSC_REAL;
177:   item->offset = ((char*)addr) - ((char*)bag);
178:   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);
179:   item->next  = 0;
180:   item->msize = msize;
181:   PetscBagRegister_Private(bag,item,name,help);
182:   return(0);
183: }

185: /*@C
186:    PetscBagRegisterInt - add an integer value to the bag

188:    Logically Collective on PetscBag

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

197:    Level: beginner

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

203: @*/
204: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault,const char *name,const char *help)
205: {
207:   PetscBagItem   item;
208:   char           nname[PETSC_BAG_NAME_LENGTH+1];
209:   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 <%d>: %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);
224:   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);
225:   item->next       = 0;
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 Parameter:
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: {
254:   PetscBagItem   item;
255:   char           nname[PETSC_BAG_NAME_LENGTH+1];
256:   PetscBool      printhelp;
257:   PetscInt       odefault = (PetscInt)mdefault;
258:   PetscBool      flg;
259: 
261:   nname[0] = '-';
262:   nname[1] = 0;
263:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
264:   PetscOptionsHasHelp(NULL,&printhelp);
265:   if (printhelp) {
266:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,odefault,help);
267:   }
268:   PetscOptionsGetInt(NULL,bag->bagprefix,nname,&odefault,&flg);
269:   if (flg) mdefault = (PetscInt64)odefault;

271:   PetscNew(&item);
272:   item->dtype  = PETSC_INT;
273:   item->offset = ((char*)addr) - ((char*)bag);
274:   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);
275:   item->next       = 0;
276:   item->msize      = 1;
277:   *(PetscInt64*)addr = mdefault;
278:   PetscBagRegister_Private(bag,item,name,help);
279:   return(0);
280: }

282: /*@C
283:    PetscBagRegisterBoolArray - add a n logical values to the bag

285:    Logically Collective on PetscBag

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

294:    Level: beginner

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

300: @*/
301: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
302: {
304:   PetscBagItem   item;
305:   char           nname[PETSC_BAG_NAME_LENGTH+1];
306:   PetscBool      printhelp;
307:   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,"%D ",*((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);
326:   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);
327:   item->next   = 0;
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 Parameter:
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: {
358:   PetscBagItem   item;
359:   char           nname[PETSC_BAG_NAME_LENGTH+1];
360:   PetscBool      printhelp;

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

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

385: /*@C
386:    PetscBagRegisterReal - add a real value to the bag

388:    Logically Collective on PetscBag

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

397:    Level: beginner

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

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

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

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

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

435:    Logically Collective on PetscBag

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


445:    Level: beginner

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

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

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

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

480: /*@C
481:    PetscBagRegisterBool - add a logical value to the bag

483:    Logically Collective on PetscBag

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


493:    Level: beginner

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

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

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

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

530: /*@C
531:    PetscBagDestroy - Destroys a bag values

533:    Collective on PetscBag

535:    Input Parameter:
536: .  bag - the bag of values

538:    Level: beginner

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

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

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

564: /*@
565:    PetscBagSetFromOptions - Allows setting options from a bag

567:    Collective on PetscBag

569:    Input Parameter:
570: .  bag - the bag of values

572:    Level: beginner

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

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

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

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

640:    Collective on PetscBag

642:    Input Parameter:
643: +  bag - the bag of values
644: -  viewer - location to view the values

646:    Level: beginner

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

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

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

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

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

764: /*@C
765:    PetscBagLoad - Loads a bag of values from a binary file

767:    Collective on PetscViewer

769:    Input Parameter:
770: +  viewer - file to load values from
771: -  bag - the bag of values

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

776:    Notes:
777:    Level: beginner

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

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

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

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

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

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

839: /*@C
840:     PetscBagCreate - Create a bag of values

842:   Collective on MPI_Comm

844:   Level: Intermediate

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

850:   Output Parameter:
851: .   bag - the bag of values

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

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

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

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

879: /*@C
880:     PetscBagSetName - Sets the name of a bag of values

882:   Not Collective

884:   Level: Intermediate

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

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

896: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
897: {

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


907: /*@C
908:     PetscBagGetName - Gets the name of a bag of values

910:   Not Collective

912:   Level: Intermediate

914:   Input Parameter:
915: .   bag - the bag of values

917:   Output Parameter:
918: .   name - the name assigned to the bag

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

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

935:   Not Collective

937:   Level: Intermediate

939:   Input Parameter:
940: .   bag - the bag of values

942:   Output Parameter:
943: .   data - pointer to memory that will have user-data-structure

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

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

960:   Logically collective on Bag.

962:   Level: Intermediate

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

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

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

974: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
975: {

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

989: /*@C
990:   PetscBagGetNames - Get the names of all entries in the bag

992:   Not collective

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

998:   Output Parameter:
999: . names - array of char pointers for names

1001:   Level: intermediate

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

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