Actual source code: bag.c
petsc-3.13.6 2020-09-29
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        = NULL;
     74:   item->msize       = 1;
     75:   PetscStrArrayallocpy(list,(char***)&item->list);
     76:   *(PetscEnum*)addr = mdefault;
     77:   PetscBagRegister_Private(bag,item,name,help);
     78:   return(0);
     79: }

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

     84:    Logically Collective on PetscBag

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

     93:    Level: beginner

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

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

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

    122:   PetscNew(&item);
    123:   item->dtype  = PETSC_INT;
    124:   item->offset = ((char*)addr) - ((char*)bag);
    125:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    126:   item->next  = NULL;
    127:   item->msize = msize;
    128:   PetscBagRegister_Private(bag,item,name,help);
    129:   return(0);
    130: }

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

    135:    Logically Collective on PetscBag

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

    144:    Level: beginner

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

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

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

    173:   PetscNew(&item);
    174:   item->dtype  = PETSC_REAL;
    175:   item->offset = ((char*)addr) - ((char*)bag);
    176:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    177:   item->next  = NULL;
    178:   item->msize = msize;
    179:   PetscBagRegister_Private(bag,item,name,help);
    180:   return(0);
    181: }

    183: /*@C
    184:    PetscBagRegisterInt - add an integer value to the bag

    186:    Logically Collective on PetscBag

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

    195:    Level: beginner

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

    201: @*/
    202: PetscErrorCode PetscBagRegisterInt(PetscBag bag,void *addr,PetscInt mdefault,const char *name,const char *help)
    203: {
    205:   PetscBagItem   item;
    206:   char           nname[PETSC_BAG_NAME_LENGTH+1];
    207:   PetscBool      printhelp;

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

    219:   PetscNew(&item);
    220:   item->dtype  = PETSC_INT;
    221:   item->offset = ((char*)addr) - ((char*)bag);
    222:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    223:   item->next       = NULL;
    224:   item->msize      = 1;
    225:   *(PetscInt*)addr = mdefault;
    226:   PetscBagRegister_Private(bag,item,name,help);
    227:   return(0);
    228: }

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

    233:    Logically Collective on PetscBag

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

    242:    Level: beginner

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

    248: @*/
    249: PetscErrorCode PetscBagRegisterInt64(PetscBag bag,void *addr,PetscInt64 mdefault,const char *name,const char *help)
    250: {
    252:   PetscBagItem   item;
    253:   char           nname[PETSC_BAG_NAME_LENGTH+1];
    254:   PetscBool      printhelp;
    255:   PetscInt       odefault = (PetscInt)mdefault;
    256:   PetscBool      flg;
    257:
    259:   nname[0] = '-';
    260:   nname[1] = 0;
    261:   PetscStrlcat(nname,name,PETSC_BAG_NAME_LENGTH);
    262:   PetscOptionsHasHelp(NULL,&printhelp);
    263:   if (printhelp) {
    264:     (*PetscHelpPrintf)(bag->bagcomm,"  -%s%s <%d>: %s \n",bag->bagprefix ? bag->bagprefix : "",name,odefault,help);
    265:   }
    266:   PetscOptionsGetInt(NULL,bag->bagprefix,nname,&odefault,&flg);
    267:   if (flg) mdefault = (PetscInt64)odefault;

    269:   PetscNew(&item);
    270:   item->dtype  = PETSC_INT;
    271:   item->offset = ((char*)addr) - ((char*)bag);
    272:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    273:   item->next       = NULL;
    274:   item->msize      = 1;
    275:   *(PetscInt64*)addr = mdefault;
    276:   PetscBagRegister_Private(bag,item,name,help);
    277:   return(0);
    278: }

    280: /*@C
    281:    PetscBagRegisterBoolArray - add a n logical values to the bag

    283:    Logically Collective on PetscBag

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

    292:    Level: beginner

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

    298: @*/
    299: PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag,void *addr,PetscInt msize, const char* name, const char* help)
    300: {
    302:   PetscBagItem   item;
    303:   char           nname[PETSC_BAG_NAME_LENGTH+1];
    304:   PetscBool      printhelp;
    305:   PetscInt       i,tmp = msize;

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

    321:   PetscNew(&item);
    322:   item->dtype  = PETSC_BOOL;
    323:   item->offset = ((char*)addr) - ((char*)bag);
    324:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    325:   item->next   = NULL;
    326:   item->msize  = msize;
    327:   PetscBagRegister_Private(bag,item,name,help);
    328:   return(0);
    329: }

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

    334:    Logically Collective on PetscBag

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

    344:    Level: beginner

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

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

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

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

    369:   PetscNew(&item);
    370:   item->dtype  = PETSC_CHAR;
    371:   item->offset = ((char*)addr) - ((char*)bag);
    372:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    373:   item->next  = NULL;
    374:   item->msize = msize;
    375:   if (mdefault != (char*)addr) {
    376:     PetscStrncpy((char*)addr,mdefault,msize-1);
    377:   }
    378:   PetscOptionsGetString(NULL,bag->bagprefix,nname,(char*)addr,msize,NULL);
    379:   PetscBagRegister_Private(bag,item,name,help);
    380:   return(0);
    381: }

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

    386:    Logically Collective on PetscBag

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

    395:    Level: beginner

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

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

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

    419:   PetscNew(&item);
    420:   item->dtype  = PETSC_REAL;
    421:   item->offset = ((char*)addr) - ((char*)bag);
    422:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    423:   item->next        = NULL;
    424:   item->msize       = 1;
    425:   *(PetscReal*)addr = mdefault;
    426:   PetscBagRegister_Private(bag,item,name,help);
    427:   return(0);
    428: }

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

    433:    Logically Collective on PetscBag

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

    443:    Level: beginner

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

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

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

    467:   PetscNew(&item);
    468:   item->dtype  = PETSC_SCALAR;
    469:   item->offset = ((char*)addr) - ((char*)bag);
    470:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    471:   item->next          = NULL;
    472:   item->msize         = 1;
    473:   *(PetscScalar*)addr = mdefault;
    474:   PetscBagRegister_Private(bag,item,name,help);
    475:   return(0);
    476: }

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

    481:    Logically Collective on PetscBag

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

    491:    Level: beginner

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

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

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

    517:   PetscNew(&item);
    518:   item->dtype  = PETSC_BOOL;
    519:   item->offset = ((char*)addr) - ((char*)bag);
    520:   if (item->offset > bag->bagsize) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Registered item %s %s is not in bag memory space",name,help);
    521:   item->next        = NULL;
    522:   item->msize       = 1;
    523:   *(PetscBool*)addr = mdefault;
    524:   PetscBagRegister_Private(bag,item,name,help);
    525:   return(0);
    526: }

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

    531:    Collective on PetscBag

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

    536:    Level: beginner

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

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

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

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

    565:    Collective on PetscBag

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

    570:    Level: beginner

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

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

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

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

    638:    Collective on PetscBag

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

    644:    Level: beginner

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

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

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

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

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

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

    765:    Collective on PetscViewer

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

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

    774:    Notes:
    775:    Level: beginner

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

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

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

    799:   PetscViewerBinaryRead(view,&classid,1,NULL,PETSC_INT);
    800:   if (classid != PETSC_BAG_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not PetscBag next in binary file");
    801:   PetscViewerBinaryRead(view,&deprecatedbagsize,1,NULL,PETSC_INT);
    802:   PetscViewerBinaryRead(view,&bagcount,1,NULL,PETSC_INT);
    803:   if (bagcount != bag->count) SETERRQ2(comm,PETSC_ERR_ARG_INCOMP,"Bag in file has different number of entries %d then passed in bag %d\n",(int)bagcount,(int)bag->count);
    804:   PetscViewerBinaryRead(view,bag->bagname,PETSC_BAG_NAME_LENGTH,NULL,PETSC_CHAR);
    805:   PetscViewerBinaryRead(view,bag->baghelp,PETSC_BAG_HELP_LENGTH,NULL,PETSC_CHAR);

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

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

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

    840:   Collective

    842:   Level: Intermediate

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

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

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

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

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

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

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

    880:   Not Collective

    882:   Level: Intermediate

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

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

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

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

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

    908:   Not Collective

    910:   Level: Intermediate

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

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

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

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

    933:   Not Collective

    935:   Level: Intermediate

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

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

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

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

    958:   Logically collective on Bag.

    960:   Level: Intermediate

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

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

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

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

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

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

    990:   Not collective

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

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

    999:   Level: intermediate

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

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