Date: 2013-07-02T14:38:35+00:00

Actual source code: bag.c
petsc-3.4.2 2013-07-02

      2: #include <petsc-private/bagimpl.h>     /*I  "petscbag.h"   I*/
      3: #include <petscviewer.h>

      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(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,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(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,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(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,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(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,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(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,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(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,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(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,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(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,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;

    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,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,NULL);
    523:       } else {
    524:         n    = nitem->msize;
    525:         PetscOptionsRealArray(name,nitem->help,"",value,&n,NULL);
    526:       }
    527:     } else if (nitem->dtype == PETSC_SCALAR) {
    528:       PetscScalar *value = (PetscScalar*)(((char*)bag) + nitem->offset);
    529:       PetscOptionsScalar(name,nitem->help,"",*value,value,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,NULL);
    534:       } else {
    535:         n    = nitem->msize;
    536:         PetscOptionsIntArray(name,nitem->help,"",value,&n,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,NULL);
    543:     } else if (nitem->dtype == PETSC_BOOL) {
    544:       PetscBool *value = (PetscBool*)(((char*)bag) + nitem->offset);
    545:       PetscOptionsBool(name,nitem->help,"",*value,value,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;

    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:     PetscViewerFormat format;
    634:     PetscViewerBinaryWrite(view,&classid,1,PETSC_INT,PETSC_TRUE);
    635:     PetscViewerBinaryWrite(view,&deprecatedbagsize,1,PETSC_INT,PETSC_FALSE);
    636:     PetscViewerBinaryWrite(view,&bag->count,1,PETSC_INT,PETSC_FALSE);
    637:     PetscViewerBinaryWrite(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
    638:     PetscViewerBinaryWrite(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
    639:     while (nitem) {
    640:       PetscViewerBinaryWrite(view,&nitem->offset,1,PETSC_INT,PETSC_FALSE);
    641:       dtype = (PetscInt)nitem->dtype;
    642:       PetscViewerBinaryWrite(view,&dtype,1,PETSC_INT,PETSC_FALSE);
    643:       PetscViewerBinaryWrite(view,nitem->name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR,PETSC_FALSE);
    644:       PetscViewerBinaryWrite(view,nitem->help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR,PETSC_FALSE);
    645:       PetscViewerBinaryWrite(view,&nitem->msize,1,PETSC_INT,PETSC_FALSE);
    646:       /* some Fortran compilers use -1 as boolean */
    647:       if (dtype == PETSC_BOOL && ((*(int*) (((char*)bag) + nitem->offset) == -1))) *(int*) (((char*)bag) + nitem->offset) = PETSC_TRUE;

    649:       PetscViewerBinaryWrite(view,(((char*)bag) + nitem->offset),nitem->msize,nitem->dtype,PETSC_FALSE);
    650:       if (dtype == PETSC_ENUM) {
    651:         PetscViewerBinaryWriteStringArray(view,(char**)nitem->list);
    652:       }
    653:       nitem = nitem->next;
    654:     }
    655:     PetscViewerGetFormat(view,&format);
    656:     if (format == PETSC_VIEWER_BINARY_MATLAB) {
    657:       MPI_Comm comm;
    658:       FILE     *info;
    659:       PetscObjectGetComm((PetscObject)view,&comm);
    660:       PetscViewerBinaryGetInfoPointer(view,&info);
    661:       PetscFPrintf(comm,info,"%%--- begin code written by PetscViewerBinary for MATLAB format ---%\n");
    662:       PetscFPrintf(comm,info,"%%$$ Set.%s = PetscBinaryRead(fd);\n",bag->bagname);
    663:       PetscFPrintf(comm,info,"%%--- end code written by PetscViewerBinary for MATLAB format ---%\n\n");
    664:     }
    665:   }
    666:   return(0);
    667: }

    671: /*@C
    672:    PetscBagLoad - Loads a bag of values from a binary file

    674:    Collective on PetscViewer

    676:    Input Parameter:
    677: +  viewer - file to load values from
    678: -  bag - the bag of values

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

    682:    Notes:
    683:    Level: beginner

    685: .seealso: PetscBag, PetscBagSetName(), PetscBagDestroy(), PetscBagView(), PetscBagGetData()
    686:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    687:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagGetName(), PetscBagRegisterEnum()

    689: @*/
    690: PetscErrorCode  PetscBagLoad(PetscViewer view,PetscBag bag)
    691: {
    693:   PetscBool      isbinary;
    694:   PetscInt       classid,bagcount,i,dtype,msize,offset,deprecatedbagsize;
    695:   char           name[PETSC_BAG_NAME_LENGTH],help[PETSC_BAG_HELP_LENGTH],**list;
    696:   PetscBagItem   nitem;
    697:   MPI_Comm       comm;
    698:   PetscMPIInt    flag;

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

    707:   PetscViewerBinaryRead(view,&classid,1,PETSC_INT);
    708:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
    709:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,PETSC_INT);
    710:   PetscViewerBinaryRead(view,&bagcount,1,PETSC_INT);
    711:   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);
    712:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
    713:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);

    715:   nitem = bag->bagitems;
    716:   for (i=0; i<bagcount; i++) {
    717:     PetscViewerBinaryRead(view,&offset,1,PETSC_INT);
    718:     /* ignore the offset in the file */
    719:     PetscViewerBinaryRead(view,&dtype,1,PETSC_INT);
    720:     PetscViewerBinaryRead(view,name,PETSC_BAG_NAME_LENGTH,PETSC_CHAR);
    721:     PetscViewerBinaryRead(view,help,PETSC_BAG_HELP_LENGTH,PETSC_CHAR);
    722:     PetscViewerBinaryRead(view,&msize,1,PETSC_INT);

    724:     if (dtype == (PetscInt) PETSC_CHAR) {
    725:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_CHAR);
    726:     } else if (dtype == (PetscInt) PETSC_REAL) {
    727:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_REAL);
    728:     } else if (dtype == (PetscInt) PETSC_SCALAR) {
    729:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_SCALAR);
    730:     } else if (dtype == (PetscInt) PETSC_INT) {
    731:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,msize,PETSC_INT);
    732:     } else if (dtype == (PetscInt) PETSC_BOOL) {
    733:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_BOOL);
    734:     } else if (dtype == (PetscInt) PETSC_ENUM) {
    735:       PetscViewerBinaryRead(view,((char*)bag)+nitem->offset,1,PETSC_ENUM);
    736:       PetscViewerBinaryReadStringArray(view,&list);
    737:       /* don't need to save list because it is already registered in the bag */
    738:       PetscFree(list);
    739:     }
    740:     nitem = nitem->next;
    741:   }
    742:   return(0);
    743: }

    747: /*@
    748:     PetscBagCreate - Create a bag of values

    750:   Collective on MPI_Comm

    752:   Level: Intermediate

    754:   Input Parameters:
    755: +  comm - communicator to share bag
    756: -  bagsize - size of the C structure holding the values

    758:   Output Parameter:
    759: .   bag - the bag of values

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

    766: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
    767:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    768:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
    769: @*/
    770: PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
    771: {
    773:   size_t         totalsize = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);

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

    780:   (*bag)->bagsize        = bagsize+sizeof(struct _n_PetscBag)+sizeof(PetscScalar);
    781:   (*bag)->bagcomm        = comm;
    782:   (*bag)->bagprefix      = NULL;
    783:   (*bag)->structlocation = (void*)(((char*)(*bag)) + sizeof(PetscScalar)*(sizeof(struct _n_PetscBag)/sizeof(PetscScalar)) + sizeof(PetscScalar));
    784:   return(0);
    785: }

    789: /*@C
    790:     PetscBagSetName - Sets the name of a bag of values

    792:   Not Collective

    794:   Level: Intermediate

    796:   Input Parameters:
    797: +   bag - the bag of values
    798: .   name - the name assigned to the bag
    799: -   help - help message for bag

    801: .seealso: PetscBag, PetscBagGetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
    802:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    803:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
    804: @*/

    806: PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
    807: {

    811:   PetscStrncpy(bag->bagname,name,PETSC_BAG_NAME_LENGTH-1);
    812:   PetscStrncpy(bag->baghelp,help,PETSC_BAG_HELP_LENGTH-1);
    813:   return(0);
    814: }

    819: /*@C
    820:     PetscBagGetName - Gets the name of a bag of values

    822:   Not Collective

    824:   Level: Intermediate

    826:   Input Parameter:
    827: .   bag - the bag of values

    829:   Output Parameter:
    830: .   name - the name assigned to the bag

    832: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad(), PetscBagGetData()
    833:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    834:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
    835: @*/
    836: PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
    837: {
    839:   *name = bag->bagname;
    840:   return(0);
    841: }

    845: /*@C
    846:     PetscBagGetData - Gives back the user - access to memory that
    847:     should be used for storing user-data-structure

    849:   Not Collective

    851:   Level: Intermediate

    853:   Input Parameter:
    854: .   bag - the bag of values

    856:   Output Parameter:
    857: .   data - pointer to memory that will have user-data-structure

    859: .seealso: PetscBag, PetscBagSetName(), PetscBagView(), PetscBagLoad()
    860:            PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    861:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
    862: @*/
    863: PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
    864: {
    866:   *data = bag->structlocation;
    867:   return(0);
    868: }

    872: /*@C
    873:   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
    874:   PetscBag items in the options database.

    876:   Logically collective on Bag.

    878:   Level: Intermediate

    880:   Input Parameters:
    881: +   bag - the bag of values
    882: -   prefix - the prefix to prepend all Bag item names with.

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

    886: .seealso: PetscBag, PetscBagRegisterReal(), PetscBagRegisterInt(), PetscBagRegisterBool(), PetscBagRegisterScalar()
    887:            PetscBagSetFromOptions(), PetscBagCreate(), PetscBagDestroy(), PetscBagRegisterEnum()
    888: @*/

    890: PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
    891: {

    895:   if (!pre) {
    896:     PetscFree(bag->bagprefix);
    897:   } else {
    898:     if (pre[0] == '-') SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Options prefix should not begin with a hypen");
    899:     PetscFree(bag->bagprefix);
    900:     PetscStrallocpy(pre,&(bag->bagprefix));
    901:   }
    902:   return(0);
    903: }