Actual source code: bag.c

petsc-3.3-p7 2013-05-11
  2: #include <../src/sys/bag/bagimpl.h>     /*I  "petscbag.h"   I*/


  7: /*
  8:       Adds item to the linked list in a bag
  9: */
 10: static PetscErrorCode PetscBagRegister_Private(PetscBag bag,PetscBagItem item,const char*name,const char*help)
 11: {

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

 31: /*@C
 32:    PetscBagRegisterEnum - add an enum value to the bag

 34:    Logically Collective on PetscBag

 36:    Input Parameter:
 37: +  bag - the bag of values
 38: .  addr - location of enum in struct
 39: .  mdefault - the initial value
 40: .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
 41: -  help - longer string with more information about the value

 43:    Level: beginner

 45: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
 46:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
 47:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName()

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

 59:   nname[0] = '-';
 60:   nname[1] = 0;
 61:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
 62:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
 63:   if (printhelp) {
 64:     while (list[i++]);
 65:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: (%s) %s (choose one of) ",bag->bagprefix?bag->bagprefix:"",name,list[mdefault],list[i-3],help);
 66:     for (i=0; list[i+2]; i++){
 67:       (*PetscHelpPrintf)(bag->bagcomm," %s",list[i]);
 68:     }
 69:     (*PetscHelpPrintf)(bag->bagcomm,"\n");
 70:   }
 71:   PetscOptionsGetEnum(bag->bagprefix,nname,list,&mdefault,PETSC_NULL);

 73:   PetscNew(struct _n_PetscBagItem,&item);
 74:   item->dtype  = PETSC_ENUM;
 75:   item->offset = ((char*)addr) - ((char*)bag);
 76:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
 77:   item->next   = 0;
 78:   item->msize  = 1;
 79:   PetscStrArrayallocpy(list,(char ***)&item->list);
 80:   *(PetscEnum*)addr = mdefault;
 81:   PetscBagRegister_Private(bag,item,name,help);
 82:   return(0);
 83: }

 87: /*@C
 88:    PetscBagRegisterIntArray - add an integer value to the bag

 90:    Logically Collective on PetscBag

 92:    Input Parameter:
 93: +  bag - the bag of values
 94: .  addr - location of integer in struct
 95: .  msize - number of entries in array
 96: .  name - name of the integer array
 97: -  help - longer string with more information about the value

 99:    Level: beginner

101: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
102:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
103:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

105: @*/
106: PetscErrorCode PetscBagRegisterIntArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
107: {
109:   PetscBagItem   item;
110:   char           nname[PETSC_BAG_NAME_LENGTH+1];
111:   PetscBool      printhelp;
112:   PetscInt       i,tmp = msize;

115:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
116:   nname[0] = '-';
117:   nname[1] = 0;
118:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
119:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
120:   if (printhelp) {
121:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix?bag->bagprefix:"",name);
122:     for (i=0; i<msize; i++) {
123:       (*PetscHelpPrintf)(bag->bagcomm,"%D ",*((PetscInt*)addr)+i);
124:   }
125:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
126:   }
127:   PetscOptionsGetIntArray(bag->bagprefix,nname,(PetscInt*)addr,&tmp,PETSC_NULL);

129:   PetscNew(struct _n_PetscBagItem,&item);
130:   item->dtype  = PETSC_INT;
131:   item->offset = ((char*)addr) - ((char*)bag);
132:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
133:   item->next   = 0;
134:   item->msize  = msize;
135:   PetscBagRegister_Private(bag,item,name,help);
136:   return(0);
137: }

141: /*@C
142:    PetscBagRegisterRealArray - add an real array to the bag

144:    Logically Collective on PetscBag

146:    Input Parameter:
147: +  bag - the bag of values
148: .  addr - location of real array in struct
149: .  msize - number of entries in array
150: .  name - name of the integer array
151: -  help - longer string with more information about the value

153:    Level: beginner

155: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
156:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
157:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

159: @*/
160: PetscErrorCode PetscBagRegisterRealArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
161: {
163:   PetscBagItem   item;
164:   char           nname[PETSC_BAG_NAME_LENGTH+1];
165:   PetscBool      printhelp;
166:   PetscInt       i,tmp = msize;

169:   /* PetscMemzero(addr,msize*sizeof(PetscInt));*/
170:   nname[0] = '-';
171:   nname[1] = 0;
172:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
173:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
174:   if (printhelp) {
175:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <",bag->bagprefix?bag->bagprefix:"",name);
176:     for (i=0; i<msize; i++) {
177:       (*PetscHelpPrintf)(bag->bagcomm,"%G ",*((PetscReal*)addr)+i);
178:   }
179:     (*PetscHelpPrintf)(bag->bagcomm,">: %s \n",help);
180:   }
181:   PetscOptionsGetRealArray(bag->bagprefix,nname,(PetscReal*)addr,&tmp,PETSC_NULL);

183:   PetscNew(struct _n_PetscBagItem,&item);
184:   item->dtype  = PETSC_REAL;
185:   item->offset = ((char*)addr) - ((char*)bag);
186:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
187:   item->next   = 0;
188:   item->msize  = msize;
189:   PetscBagRegister_Private(bag,item,name,help);
190:   return(0);
191: }

195: /*@C
196:    PetscBagRegisterInt - add an integer value to the bag

198:    Logically Collective on PetscBag

200:    Input Parameter:
201: +  bag - the bag of values
202: .  addr - location of integer in struct
203: .  mdefault - the initial value
204: .  name - name of the integer
205: -  help - longer string with more information about the value

207:    Level: beginner

209: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
210:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
211:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

213: @*/
214: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault, const char* name, const char* help)
215: {
217:   PetscBagItem   item;
218:   char           nname[PETSC_BAG_NAME_LENGTH+1];
219:   PetscBool      printhelp;

222:   nname[0] = '-';
223:   nname[1] = 0;
224:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
225:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
226:   if (printhelp) {
227:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
228:   }
229:   PetscOptionsGetInt(bag->bagprefix,nname,&mdefault,PETSC_NULL);

231:   PetscNew(struct _n_PetscBagItem,&item);
232:   item->dtype  = PETSC_INT;
233:   item->offset = ((char*)addr) - ((char*)bag);
234:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
235:   item->next   = 0;
236:   item->msize  = 1;
237:   *(PetscInt*)addr = mdefault;
238:   PetscBagRegister_Private(bag,item,name,help);
239:   return(0);
240: }

244: /*@C
245:    PetscBagRegisterString - add a string value to the bag

247:    Logically Collective on PetscBag

249:    Input Parameter:
250: +  bag - the bag of values
251: .  addr - location of start of string in struct
252: .  msize - length of the string space in the struct
253: .  mdefault - the initial value
254: .  name - name of the string
255: -  help - longer string with more information about the value

257:    Level: beginner

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

261: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
262:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
263:            PetscBagSetFromOptions(),PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

265: @*/
266: PetscErrorCode PetscBagRegisterString(PetscBag bag,void *addr,PetscInt msize,const char* mdefault, const char* name, const char* help)
267: {
269:   PetscBagItem   item;
270:   char           nname[PETSC_BAG_NAME_LENGTH+1];
271:   PetscBool      printhelp;

274:   nname[0] = '-';
275:   nname[1] = 0;
276:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
277:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
278:   if (printhelp) {
279:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,mdefault,help);
280:   }

282:   PetscNew(struct _n_PetscBagItem,&item);
283:   item->dtype  = PETSC_CHAR;
284:   item->offset = ((char*)addr) - ((char*)bag);
285:   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);
286:   item->next   = 0;
287:   item->msize  = msize;
288:   if (mdefault != (char*)addr) {
289:     PetscStrncpy((char*)addr,mdefault,msize-1);
290:   }
291:   PetscOptionsGetString(bag->bagprefix,nname,(char*)addr,msize,PETSC_NULL);
292:   PetscBagRegister_Private(bag,item,name,help);
293:   return(0);
294: }

298: /*@C
299:    PetscBagRegisterReal - add a real value to the bag

301:    Logically Collective on PetscBag

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

310:    Level: beginner

312: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
313:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
314:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

316: @*/
317: PetscErrorCode PetscBagRegisterReal(PetscBag bag,void *addr,PetscReal mdefault, const char* name, const char* help)
318: {
320:   PetscBagItem   item;
321:   char           nname[PETSC_BAG_NAME_LENGTH+1];
322:   PetscBool      printhelp;

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

334:   PetscNew(struct _n_PetscBagItem,&item);
335:   item->dtype  = PETSC_REAL;
336:   item->offset = ((char*)addr) - ((char*)bag);
337:   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);
338:   item->next   = 0;
339:   item->msize  = 1;
340:   *(PetscReal*)addr = mdefault;
341:   PetscBagRegister_Private(bag,item,name,help);
342:   return(0);
343: }

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

350:    Logically Collective on PetscBag

352:    Input Parameter:
353: +  bag - the bag of values
354: .  addr - location of scalar in struct
355: .  mdefault - the initial value
356: .  name - name of the variable
357: -  help - longer string with more information about the value


360:    Level: beginner

362: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
363:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
364:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

366: @*/
367: PetscErrorCode PetscBagRegisterScalar(PetscBag bag,void *addr,PetscScalar mdefault, const char* name, const char* help)
368: {
370:   PetscBagItem   item;
371:   char           nname[PETSC_BAG_NAME_LENGTH+1];
372:   PetscBool      printhelp;

375:   nname[0] = '-';
376:   nname[1] = 0;
377:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
378:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
379:   if (printhelp) {
380:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%G + %Gi>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscRealPart(mdefault),PetscImaginaryPart(mdefault),help);
381:   }
382:   PetscOptionsGetScalar(bag->bagprefix,nname,&mdefault,PETSC_NULL);

384:   PetscNew(struct _n_PetscBagItem,&item);
385:   item->dtype  = PETSC_SCALAR;
386:   item->offset = ((char*)addr) - ((char*)bag);
387:   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);
388:   item->next   = 0;
389:   item->msize  = 1;
390:   *(PetscScalar*)addr = mdefault;
391:   PetscBagRegister_Private(bag,item,name,help);
392:   return(0);
393: }

397: /*@C
398:    PetscBagRegisterBool - add a logical value to the bag

400:    Logically Collective on PetscBag

402:    Input Parameter:
403: +  bag - the bag of values
404: .  addr - location of logical in struct
405: .  mdefault - the initial value
406: .  name - name of the variable
407: -  help - longer string with more information about the value


410:    Level: beginner

412: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
413:            PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
414:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

416: @*/
417: PetscErrorCode PetscBagRegisterBool(PetscBag bag,void *addr,PetscBool  mdefault, const char* name, const char* help)
418: {
420:   PetscBagItem   item;
421:   char           nname[PETSC_BAG_NAME_LENGTH+1];
422:   PetscBool      printhelp;

425:   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
426:   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);
427:   nname[0] = '-';
428:   nname[1] = 0;
429:   PetscStrncat(nname,name,PETSC_BAG_NAME_LENGTH-1);
430:   PetscOptionsHasName(PETSC_NULL,"-help",&printhelp);
431:   if (printhelp) {
432:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%s>: %s \n",bag->bagprefix?bag->bagprefix:"",name,PetscBools[mdefault],help);
433:   }
434:   PetscOptionsGetBool(bag->bagprefix,nname,&mdefault,PETSC_NULL);

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

449: /*@C
450:    PetscBagDestroy - Destroys a bag values

452:    Collective on PetscBag

454:    Input Parameter:
455: .  bag - the bag of values

457:    Level: beginner

459: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
460:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
461:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

463: @*/
464: PetscErrorCode  PetscBagDestroy(PetscBag *bag)
465: {
467:   PetscBagItem   nitem = (*bag)->bagitems,item;

470:   while (nitem) {
471:     item  = nitem->next;
472:     if (nitem->list) {
473:       PetscStrArrayDestroy(&nitem->list);
474:     }
475:     PetscFree(nitem);
476:     nitem = item;
477:   }
478:   if ((*bag)->bagprefix) { PetscFree((*bag)->bagprefix); }
479:   PetscFree(*bag);
480:   return(0);
481: }

485: /*@
486:    PetscBagSetFromOptions - Allows setting options from a bag

488:    Collective on PetscBag

490:    Input Parameter:
491: .  bag - the bag of values

493:    Level: beginner

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

499: @*/
500: PetscErrorCode  PetscBagSetFromOptions(PetscBag bag)
501: {
503:   PetscBagItem   nitem = bag->bagitems;
504:   char           name[PETSC_BAG_NAME_LENGTH+1],helpname[PETSC_BAG_NAME_LENGTH+PETSC_BAG_HELP_LENGTH+3];
505:   PetscInt       n;
506: 
508:   PetscStrcpy(helpname,bag->bagname);
509:   PetscStrcat(helpname," ");
510:   PetscStrcat(helpname,bag->baghelp);
511:   PetscOptionsBegin(bag->bagcomm,bag->bagprefix,helpname,0);
512:     while (nitem) {
513:       name[0] = '-';
514:       name[1] = 0;
515:       PetscStrcat(name,nitem->name);
516:       if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
517:         char *value = (char*)(((char*)bag) + nitem->offset);
518:         PetscOptionsString(name,nitem->help,"",value,value,nitem->msize,PETSC_NULL);
519:       } else if (nitem->dtype == PETSC_REAL) {
520:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
521:         if (nitem->msize == 1) {
522:           PetscOptionsReal(name,nitem->help,"",*value,value,PETSC_NULL);
523:         } else {
524:           n = nitem->msize;
525:           PetscOptionsRealArray(name,nitem->help,"",value,&n,PETSC_NULL);
526:         }
527:       } else if (nitem->dtype == PETSC_SCALAR) {
528:         PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
529:         PetscOptionsScalar(name,nitem->help,"",*value,value,PETSC_NULL);
530:       } else if (nitem->dtype == PETSC_INT) {
531:         PetscInt *value = (PetscInt*)(((char*)bag) + nitem->offset);
532:         if (nitem->msize == 1) {
533:           PetscOptionsInt(name,nitem->help,"",*value,value,PETSC_NULL);
534:         } else {
535:           n = nitem->msize;
536:           PetscOptionsIntArray(name,nitem->help,"",value,&n,PETSC_NULL);
537:         }
538:       } else if (nitem->dtype == PETSC_ENUM) {
539:         PetscEnum *value = (PetscEnum*)(((char*)bag) + nitem->offset);
540:         PetscInt  i = 0;
541:         while (nitem->list[i++]);
542:         PetscOptionsEnum(name,nitem->help,nitem->list[i-3],(const char*const*)nitem->list,*value,value,PETSC_NULL);
543:       } else if (nitem->dtype == PETSC_BOOL) {
544:         PetscBool  *value = (PetscBool*)(((char*)bag) + nitem->offset);
545:         PetscOptionsBool(name,nitem->help,"",*value,value,PETSC_NULL);
546:       }
547:       nitem = nitem->next;
548:     }
549:   PetscOptionsEnd();
550:   return(0);
551: }

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

558:    Collective on PetscBag

560:    Input Parameter:
561: +  bag - the bag of values
562: -  viewer - location to view the values

564:    Level: beginner

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

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

574: @*/
575: PetscErrorCode  PetscBagView(PetscBag bag,PetscViewer view)
576: {
577:   PetscBool      isascii,isbinary;
579:   PetscBagItem   nitem = bag->bagitems;
580: 
582:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERASCII,&isascii);
583:   PetscObjectTypeCompare((PetscObject)view,PETSCVIEWERBINARY,&isbinary);
584:   if (isascii) {
585:     PetscViewerASCIIPrintf(view,"PetscBag Object:  %s %s\n",bag->bagname,bag->baghelp);
586:     while (nitem) {
587:       if (nitem->dtype == PETSC_CHAR) {
588:         char* value = (char*)(((char*)bag) + nitem->offset);
589:         char tmp = value[nitem->msize-1];  /* special handling for fortran chars wihout null terminator */
590:         value[nitem->msize-1] =0;
591:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,value,nitem->help);
592:         value[nitem->msize-1] =tmp;
593:       } else if (nitem->dtype == PETSC_REAL) {
594:         PetscReal *value = (PetscReal*)(((char*)bag) + nitem->offset);
595:         PetscInt  i;
596:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
597:         for (i=0; i<nitem->msize; i++) {
598:           PetscViewerASCIIPrintf(view,"%G ",value[i]);
599:         }
600:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
601:       } else if (nitem->dtype == PETSC_SCALAR) {
602:         PetscScalar value = *(PetscScalar*)(((char*)bag) + nitem->offset);
603: #if defined(PETSC_USE_COMPLEX)
604:         PetscViewerASCIIPrintf(view,"  %s = %G + %Gi; %s\n",nitem->name,PetscRealPart(value),PetscImaginaryPart(value),nitem->help);
605: #else
606:         PetscViewerASCIIPrintf(view,"  %s = %G; %s\n",nitem->name,value,nitem->help);
607: #endif
608:       } else if (nitem->dtype == PETSC_INT) {
609:         PetscInt i,*value = (PetscInt*)(((char*)bag) + nitem->offset);
610:         PetscViewerASCIIPrintf(view,"  %s = ",nitem->name);
611:         for (i=0; i<nitem->msize; i++) {
612:           PetscViewerASCIIPrintf(view,"%D ",value[i]);
613:         }
614:         PetscViewerASCIIPrintf(view,"; %s\n",nitem->help);
615:       } else if (nitem->dtype == PETSC_BOOL) {
616:         PetscBool  value = *(PetscBool*)(((char*)bag) + nitem->offset);
617:         /* some Fortran compilers use -1 as boolean */
618:         if (((int) value) == -1) value = PETSC_TRUE;
619:         /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
620:         if (value != PETSC_FALSE && value != PETSC_TRUE) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Boolean value for %s %s is corrupt; integer value %d",nitem->name,nitem->help,value);
621:         PetscViewerASCIIPrintf(view,"  %s = %s; %s\n",nitem->name,PetscBools[value],nitem->help);
622:       } else if (nitem->dtype == PETSC_ENUM) {
623:         PetscEnum value = *(PetscEnum*)(((char*)bag) + nitem->offset);
624:         PetscInt  i = 0;
625:         while (nitem->list[i++]);
626:         PetscViewerASCIIPrintf(view,"  %s = %s; (%s) %s\n",nitem->name,nitem->list[value],nitem->list[i-3],nitem->help);
627:       }
628:       nitem = nitem->next;
629:     }
630:   } else if (isbinary) {
631:     PetscInt classid = PETSC_BAG_FILE_CLASSID, dtype;
632:     PetscInt deprecatedbagsize = 0;
633:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
634:     PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);
635:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
636:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
637:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
638:     while (nitem) {
639:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
640:       dtype = (PetscInt)nitem->dtype;
641:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
642:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
643:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
644:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
645:       /* some Fortran compilers use -1 as boolean */
646:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

648:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
649:       if (dtype == PETSC_ENUM) {
650:         PetscViewerBinaryWriteStringArray(view,(char **)nitem->list);
651:       }
652:       nitem = nitem->next;
653:     }
654:   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for this viewer type");
655:   return(0);
656: }

660: /*@C
661:    PetscBagLoad - Loads a bag of values from a binary file

663:    Collective on PetscViewer

665:    Input Parameter:
666: +  viewer - file to load values from
667: -  bag - the bag of values

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

671:    Notes: 
672:    Level: beginner

674: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
675:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
676:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

678: @*/
679: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
680: {
682:   PetscBool      isbinary;
683:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
684:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
685:   PetscBagItem   nitem;
686:   MPI_Comm       comm;
687:   PetscMPIInt    flag;

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

696:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
697:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
698:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,PETSC_INT);
699:   PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);
700:   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);
701:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
702:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

704:   nitem = bag->bagitems;
705:   for (i=0; i<bagcount; i++) {
706:     PetscViewerBinaryRead(view,&offset,1,PETSC_INT);
707:     /* ignore the offset in the file */
708:     PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);
709:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
710:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
711:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

713:     if (dtype == (PetscInt) PETSC_CHAR) {
714:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);
715:     } else if (dtype == (PetscInt) PETSC_REAL) {
716:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_REAL);
717:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
718:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);
719:     } else if (dtype == (PetscInt) PETSC_INT) {
720:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_INT);
721:     } else if (dtype == (PetscInt) PETSC_BOOL) {
722:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_BOOL);
723:     } else if (dtype == (PetscInt) PETSC_ENUM) {
724:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);
725:       PetscViewerBinaryReadStringArray(view,&list);
726:       /* don't need to save list because it is already registered in the bag */
727:       PetscFree(list);
728:     }
729:     nitem = nitem->next;
730:   }
731:   return(0);
732: }

736: /*@
737:     PetscBagCreate - Create a bag of values

739:   Collective on MPI_Comm

741:   Level: Intermediate

743:   Input Parameters:
744: +  comm - communicator to share bag
745: -  bagsize - size of the C structure holding the values

747:   Output Parameter:
748: .   bag - the bag of values

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

755: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
756:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
757:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
758: @*/
759: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
760: {
762:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

765:   PetscInfo1(PETSC_NULL,"Creating Bag with total size %d\n",(int)totalsize);
766:   PetscMalloc(totalsize,bag);
767:   PetscMemzero(*bag,bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar));
768:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
769:   (*bag)->bagcomm        = comm;
770:   (*bag)->bagprefix      = PETSC_NULL;
771:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
772:   return(0);
773: }
774: 
777: /*@C
778:     PetscBagSetName - Sets the name of a bag of values

780:   Not Collective

782:   Level: Intermediate

784:   Input Parameters:
785: +   bag - the bag of values
786: .   name - the name assigned to the bag
787: -   help - help message for bag

789: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
790:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
791:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
792: @*/

794: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
795: {
798:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
799:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
800:   return(0);
801: }


806: /*@C
807:     PetscBagGetName - Gets the name of a bag of values

809:   Not Collective

811:   Level: Intermediate

813:   Input Parameter:
814: .   bag - the bag of values

816:   Output Parameter:
817: .   name - the name assigned to the bag

819: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
820:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
821:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
822: @*/
823: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
824: {
826:   *name = bag->bagname;
827:   return(0);
828: }

832: /*@C
833:     PetscBagGetData - Gives back the user - access to memory that
834:     should be used for storing user-data-structure

836:   Not Collective

838:   Level: Intermediate

840:   Input Parameter:
841: .   bag - the bag of values

843:   Output Parameter:
844: .   data - pointer to memory that will have user-data-structure

846: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
847:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
848:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
849: @*/
850: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
851: {
853:   *data = bag->structlocation;
854:   return(0);
855: }

859: /*@C
860:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
861:   PetscBag items in the options database.

863:   Logically collective on Bag.

865:   Level: Intermediate

867:   Input Parameters:
868: +   bag - the bag of values
869: -   prefix - the prefix to prepend all Bag item names with.

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

873: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
874:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
875: @*/

877: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
878: {
881:   if (!pre) {
882:     PetscFree(bag->bagprefix);
883:   } else {
884:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
885:     PetscFree(bag->bagprefix);
886:     PetscStrallocpy(pre,&(bag->bagprefix));
887:   }
888:   return(0);
889: }