xref: /petsc/src/sys/classes/bag/bag.c (revision 09cbc92a5f7c7b3977ad1973773b74ce8d2adce8)
15f80ce2aSJacob Faibussowitsch #include <petsc/private/petscimpl.h>
2af0996ceSBarry Smith #include <petsc/private/bagimpl.h> /*I  "petscbag.h"   I*/
3665c2dedSJed Brown #include <petscviewer.h>
45c6c1daeSBarry Smith 
55c6c1daeSBarry Smith /*
65c6c1daeSBarry Smith       Adds item to the linked list in a bag
75c6c1daeSBarry Smith */
8d71ae5a4SJacob Faibussowitsch static PetscErrorCode PetscBagRegister_Private(PetscBag bag, PetscBagItem item, const char *name, const char *help)
9d71ae5a4SJacob Faibussowitsch {
105c6c1daeSBarry Smith   PetscFunctionBegin;
119566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(item->name, name, PETSC_BAG_NAME_LENGTH - 1));
129566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(item->help, help, PETSC_BAG_HELP_LENGTH - 1));
135f80ce2aSJacob Faibussowitsch   if (bag->bagitems) {
145c6c1daeSBarry Smith     PetscBagItem nitem = bag->bagitems;
155f80ce2aSJacob Faibussowitsch 
165f80ce2aSJacob Faibussowitsch     while (nitem->next) nitem = nitem->next;
175c6c1daeSBarry Smith     nitem->next = item;
185f80ce2aSJacob Faibussowitsch   } else bag->bagitems = item;
195c6c1daeSBarry Smith   bag->count++;
203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
215c6c1daeSBarry Smith }
225c6c1daeSBarry Smith 
235c6c1daeSBarry Smith /*@C
24811af0c4SBarry Smith    PetscBagRegisterEnum - add an enum value to a `PetscBag`
255c6c1daeSBarry Smith 
26c3339decSBarry Smith    Logically Collective
275c6c1daeSBarry Smith 
28d8d19677SJose E. Roman    Input Parameters:
295c6c1daeSBarry Smith +  bag - the bag of values
30811af0c4SBarry Smith .  addr - location of enum in struct, for example `&params->dt`
315c6c1daeSBarry Smith .  list - array of strings containing names of enum values followed by enum name followed by enum prefix
32811af0c4SBarry Smith .  mdefault - the initial value, cast with (`PetscEnum`)
335c6c1daeSBarry Smith -  help - longer string with more information about the value
345c6c1daeSBarry Smith 
355c6c1daeSBarry Smith    Level: beginner
365c6c1daeSBarry Smith 
37db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
38db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
39db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
405c6c1daeSBarry Smith @*/
41d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help)
42d71ae5a4SJacob Faibussowitsch {
435c6c1daeSBarry Smith   PetscBagItem item;
445c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
455c6c1daeSBarry Smith   PetscBool    printhelp;
465c6c1daeSBarry Smith   PetscInt     i = 0;
475c6c1daeSBarry Smith 
485c6c1daeSBarry Smith   PetscFunctionBegin;
495f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
505f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
515f80ce2aSJacob Faibussowitsch   PetscValidPointer(list, 3);
525f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 5);
535f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 6);
545c6c1daeSBarry Smith   nname[0] = '-';
555c6c1daeSBarry Smith   nname[1] = 0;
569566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
585c6c1daeSBarry Smith   if (printhelp) {
599371c9d4SSatish Balay     while (list[i++])
609371c9d4SSatish Balay       ;
619566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help));
629566063dSJacob Faibussowitsch     for (i = 0; list[i + 2]; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " %s", list[i]));
639566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "\n"));
645c6c1daeSBarry Smith   }
659566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL));
665c6c1daeSBarry Smith 
679566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
685c6c1daeSBarry Smith   item->dtype  = PETSC_ENUM;
695c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
705f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
7102c9f0b5SLisandro Dalcin   item->next  = NULL;
725c6c1daeSBarry Smith   item->msize = 1;
739566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(list, (char ***)&item->list));
745c6c1daeSBarry Smith   *(PetscEnum *)addr = mdefault;
759566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
775c6c1daeSBarry Smith }
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith /*@C
80*09cbc92aSBarry Smith    PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag`
815c6c1daeSBarry Smith 
82c3339decSBarry Smith    Logically Collective
835c6c1daeSBarry Smith 
84d8d19677SJose E. Roman    Input Parameters:
855c6c1daeSBarry Smith +  bag - the bag of values
86811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
875c6c1daeSBarry Smith .  msize - number of entries in array
88811af0c4SBarry Smith .  name - name of the array
895c6c1daeSBarry Smith -  help - longer string with more information about the value
905c6c1daeSBarry Smith 
915c6c1daeSBarry Smith    Level: beginner
925c6c1daeSBarry Smith 
93db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
94db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
95db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
965c6c1daeSBarry Smith @*/
97d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
98d71ae5a4SJacob Faibussowitsch {
995c6c1daeSBarry Smith   PetscBagItem item;
1005c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
1015c6c1daeSBarry Smith   PetscBool    printhelp;
1025c6c1daeSBarry Smith   PetscInt     i, tmp = msize;
1035c6c1daeSBarry Smith 
1045c6c1daeSBarry Smith   PetscFunctionBegin;
1055f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
1065f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
1075f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
1085f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
1095c6c1daeSBarry Smith   nname[0] = '-';
1105c6c1daeSBarry Smith   nname[1] = 0;
1119566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
1129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
1135c6c1daeSBarry Smith   if (printhelp) {
1149566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
11548a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i));
1169566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
1175c6c1daeSBarry Smith   }
1189566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, (PetscInt *)addr, &tmp, NULL));
1195c6c1daeSBarry Smith 
1209566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
1215c6c1daeSBarry Smith   item->dtype  = PETSC_INT;
1225c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
1235f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
12402c9f0b5SLisandro Dalcin   item->next  = NULL;
1255c6c1daeSBarry Smith   item->msize = msize;
1269566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
1273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1285c6c1daeSBarry Smith }
1295c6c1daeSBarry Smith 
1305c6c1daeSBarry Smith /*@C
131*09cbc92aSBarry Smith    PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag`
1325c6c1daeSBarry Smith 
133c3339decSBarry Smith    Logically Collective
1345c6c1daeSBarry Smith 
135d8d19677SJose E. Roman    Input Parameters:
1365c6c1daeSBarry Smith +  bag - the bag of values
137811af0c4SBarry Smith .  addr - location of real array in struct, for example `&params->d`
138811af0c4SBarry Smith .  msize - number of entries in the array
139811af0c4SBarry Smith .  name - name of the array
1405c6c1daeSBarry Smith -  help - longer string with more information about the value
1415c6c1daeSBarry Smith 
1425c6c1daeSBarry Smith    Level: beginner
1435c6c1daeSBarry Smith 
144db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
145db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
146db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
1475c6c1daeSBarry Smith @*/
148d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
149d71ae5a4SJacob Faibussowitsch {
1505c6c1daeSBarry Smith   PetscBagItem item;
1515c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
1525c6c1daeSBarry Smith   PetscBool    printhelp;
1535c6c1daeSBarry Smith   PetscInt     i, tmp = msize;
1545c6c1daeSBarry Smith 
1555c6c1daeSBarry Smith   PetscFunctionBegin;
1565f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
1575f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
1585f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
1595f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
1605c6c1daeSBarry Smith   nname[0] = '-';
1615c6c1daeSBarry Smith   nname[1] = 0;
1629566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
1639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
1645c6c1daeSBarry Smith   if (printhelp) {
1659566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
16648a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)*((PetscReal *)addr) + i));
1679566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
1685c6c1daeSBarry Smith   }
1699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, (PetscReal *)addr, &tmp, NULL));
1705c6c1daeSBarry Smith 
1719566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
1725c6c1daeSBarry Smith   item->dtype  = PETSC_REAL;
1735c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
1745f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
17502c9f0b5SLisandro Dalcin   item->next  = NULL;
1765c6c1daeSBarry Smith   item->msize = msize;
1779566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
1783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1795c6c1daeSBarry Smith }
1805c6c1daeSBarry Smith 
1815c6c1daeSBarry Smith /*@C
182*09cbc92aSBarry Smith    PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag`
1835c6c1daeSBarry Smith 
184c3339decSBarry Smith    Logically Collective
1855c6c1daeSBarry Smith 
186d8d19677SJose E. Roman    Input Parameters:
1875c6c1daeSBarry Smith +  bag - the bag of values
188811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
1895c6c1daeSBarry Smith .  mdefault - the initial value
1905c6c1daeSBarry Smith .  name - name of the integer
1915c6c1daeSBarry Smith -  help - longer string with more information about the value
1925c6c1daeSBarry Smith 
1935c6c1daeSBarry Smith    Level: beginner
1945c6c1daeSBarry Smith 
195db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
196db781477SPatrick Sanan           `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
197db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
1985c6c1daeSBarry Smith @*/
199d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help)
200d71ae5a4SJacob Faibussowitsch {
2015c6c1daeSBarry Smith   PetscBagItem item;
2025c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
2035c6c1daeSBarry Smith   PetscBool    printhelp;
2045c6c1daeSBarry Smith 
2055c6c1daeSBarry Smith   PetscFunctionBegin;
2065f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
2075f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
2085f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
2095f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
2105c6c1daeSBarry Smith   nname[0] = '-';
2115c6c1daeSBarry Smith   nname[1] = 0;
2129566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
2139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
21448a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
2159566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL));
2165c6c1daeSBarry Smith 
2179566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
2185c6c1daeSBarry Smith   item->dtype  = PETSC_INT;
2195c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
2205f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
22102c9f0b5SLisandro Dalcin   item->next        = NULL;
2225c6c1daeSBarry Smith   item->msize       = 1;
2235c6c1daeSBarry Smith   *(PetscInt *)addr = mdefault;
2249566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
2253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2265c6c1daeSBarry Smith }
2275c6c1daeSBarry Smith 
2280d349d43SBarry Smith /*@C
229811af0c4SBarry Smith    PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`
2300d349d43SBarry Smith 
231c3339decSBarry Smith    Logically Collective
2320d349d43SBarry Smith 
233d8d19677SJose E. Roman    Input Parameters:
2340d349d43SBarry Smith +  bag - the bag of values
235811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
2360d349d43SBarry Smith .  mdefault - the initial value
2370d349d43SBarry Smith .  name - name of the integer
2380d349d43SBarry Smith -  help - longer string with more information about the value
2390d349d43SBarry Smith 
2400d349d43SBarry Smith    Level: beginner
2410d349d43SBarry Smith 
242db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
243db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
244db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
2450d349d43SBarry Smith @*/
246d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help)
247d71ae5a4SJacob Faibussowitsch {
2480d349d43SBarry Smith   PetscBagItem item;
2490d349d43SBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
2500d349d43SBarry Smith   PetscBool    printhelp;
2510d349d43SBarry Smith   PetscInt     odefault = (PetscInt)mdefault;
2520d349d43SBarry Smith   PetscBool    flg;
2530d349d43SBarry Smith 
2540d349d43SBarry Smith   PetscFunctionBegin;
2550d349d43SBarry Smith   nname[0] = '-';
2560d349d43SBarry Smith   nname[1] = 0;
2579566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
2589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
25948a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help));
2609566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg));
261bafee8b4SSatish Balay   if (flg) mdefault = (PetscInt64)odefault;
2620d349d43SBarry Smith 
2639566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
2640d349d43SBarry Smith   item->dtype  = PETSC_INT;
2650d349d43SBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
2665f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
26702c9f0b5SLisandro Dalcin   item->next          = NULL;
2680d349d43SBarry Smith   item->msize         = 1;
269bafee8b4SSatish Balay   *(PetscInt64 *)addr = mdefault;
2709566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
2713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2720d349d43SBarry Smith }
2730d349d43SBarry Smith 
274dd66f111SBlaise Bourdin /*@C
275811af0c4SBarry Smith    PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`
276dd66f111SBlaise Bourdin 
277c3339decSBarry Smith    Logically Collective
278dd66f111SBlaise Bourdin 
279d8d19677SJose E. Roman    Input Parameters:
280dd66f111SBlaise Bourdin +  bag - the bag of values
281811af0c4SBarry Smith .  addr - location of boolean array in struct, for example `&params->b`
282dd66f111SBlaise Bourdin .  msize - number of entries in array
283dd66f111SBlaise Bourdin .  name - name of the boolean array
284dd66f111SBlaise Bourdin -  help - longer string with more information about the value
285dd66f111SBlaise Bourdin 
286dd66f111SBlaise Bourdin    Level: beginner
287dd66f111SBlaise Bourdin 
288db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
289db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
290db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
291dd66f111SBlaise Bourdin @*/
292d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
293d71ae5a4SJacob Faibussowitsch {
294dd66f111SBlaise Bourdin   PetscBagItem item;
295dd66f111SBlaise Bourdin   char         nname[PETSC_BAG_NAME_LENGTH + 1];
296dd66f111SBlaise Bourdin   PetscBool    printhelp;
297dd66f111SBlaise Bourdin   PetscInt     i, tmp = msize;
298dd66f111SBlaise Bourdin 
299dd66f111SBlaise Bourdin   PetscFunctionBegin;
3005f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
3015f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
3025f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
3035f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
304dd66f111SBlaise Bourdin   nname[0] = '-';
305dd66f111SBlaise Bourdin   nname[1] = 0;
3069566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
3079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
308dd66f111SBlaise Bourdin   if (printhelp) {
3099566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
31048a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i));
3119566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
312dd66f111SBlaise Bourdin   }
3139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, (PetscBool *)addr, &tmp, NULL));
314dd66f111SBlaise Bourdin 
3159566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
316dd66f111SBlaise Bourdin   item->dtype  = PETSC_BOOL;
317dd66f111SBlaise Bourdin   item->offset = ((char *)addr) - ((char *)bag);
3185f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
31902c9f0b5SLisandro Dalcin   item->next  = NULL;
320dd66f111SBlaise Bourdin   item->msize = msize;
3219566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
3223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
323dd66f111SBlaise Bourdin }
324dd66f111SBlaise Bourdin 
3255c6c1daeSBarry Smith /*@C
326811af0c4SBarry Smith    PetscBagRegisterString - add a string value to a `PetscBag`
3275c6c1daeSBarry Smith 
328c3339decSBarry Smith    Logically Collective
3295c6c1daeSBarry Smith 
330d8d19677SJose E. Roman    Input Parameters:
3315c6c1daeSBarry Smith +  bag - the bag of values
332811af0c4SBarry Smith .  addr - location of start of string in struct, for example `&params->mystring`
3335c6c1daeSBarry Smith .  msize - length of the string space in the struct
3345c6c1daeSBarry Smith .  mdefault - the initial value
3355c6c1daeSBarry Smith .  name - name of the string
3365c6c1daeSBarry Smith -  help - longer string with more information about the value
3375c6c1daeSBarry Smith 
3385c6c1daeSBarry Smith    Level: beginner
3395c6c1daeSBarry Smith 
340*09cbc92aSBarry Smith    Note:
341*09cbc92aSBarry Smith    The struct must have the field char mystring[`msize`]; not char *mystring
3425c6c1daeSBarry Smith 
343db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
344db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
345c2e3fba1SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
3465c6c1daeSBarry Smith @*/
347d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help)
348d71ae5a4SJacob Faibussowitsch {
3495c6c1daeSBarry Smith   PetscBagItem item;
3505c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
3515c6c1daeSBarry Smith   PetscBool    printhelp;
3525c6c1daeSBarry Smith 
3535c6c1daeSBarry Smith   PetscFunctionBegin;
3545f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
3555f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
3565f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(mdefault, 4);
3575f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 5);
3585f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 6);
3595c6c1daeSBarry Smith   nname[0] = '-';
3605c6c1daeSBarry Smith   nname[1] = 0;
3619566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
3629566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
36348a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
3645c6c1daeSBarry Smith 
3659566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
3665c6c1daeSBarry Smith   item->dtype  = PETSC_CHAR;
3675c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
3685f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
36902c9f0b5SLisandro Dalcin   item->next  = NULL;
3705c6c1daeSBarry Smith   item->msize = msize;
37148a46eb9SPierre Jolivet   if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1));
3729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL));
3739566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
3743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3755c6c1daeSBarry Smith }
3765c6c1daeSBarry Smith 
3775c6c1daeSBarry Smith /*@C
378811af0c4SBarry Smith    PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`
3795c6c1daeSBarry Smith 
380c3339decSBarry Smith    Logically Collective
3815c6c1daeSBarry Smith 
382d8d19677SJose E. Roman    Input Parameters:
3835c6c1daeSBarry Smith +  bag - the bag of values
384*09cbc92aSBarry Smith .  addr - location of `PetscReal` in struct, for example `&params->r`
3855c6c1daeSBarry Smith .  mdefault - the initial value
3865c6c1daeSBarry Smith .  name - name of the variable
3875c6c1daeSBarry Smith -  help - longer string with more information about the value
3885c6c1daeSBarry Smith 
3895c6c1daeSBarry Smith    Level: beginner
3905c6c1daeSBarry Smith 
391db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
392db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
393db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
3945c6c1daeSBarry Smith @*/
395d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help)
396d71ae5a4SJacob Faibussowitsch {
3975c6c1daeSBarry Smith   PetscBagItem item;
3985c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
3995c6c1daeSBarry Smith   PetscBool    printhelp;
4005c6c1daeSBarry Smith 
4015c6c1daeSBarry Smith   PetscFunctionBegin;
4025f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4035f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4045f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
4055f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
4065c6c1daeSBarry Smith   nname[0] = '-';
4075c6c1daeSBarry Smith   nname[1] = 0;
4089566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
4099566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
41048a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help));
4119566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL));
4125c6c1daeSBarry Smith 
4139566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
4145c6c1daeSBarry Smith   item->dtype  = PETSC_REAL;
4155c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
4165f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
41702c9f0b5SLisandro Dalcin   item->next         = NULL;
4185c6c1daeSBarry Smith   item->msize        = 1;
4195c6c1daeSBarry Smith   *(PetscReal *)addr = mdefault;
4209566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
4213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4225c6c1daeSBarry Smith }
4235c6c1daeSBarry Smith 
4245c6c1daeSBarry Smith /*@C
425811af0c4SBarry Smith    PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`
4265c6c1daeSBarry Smith 
427c3339decSBarry Smith    Logically Collective
4285c6c1daeSBarry Smith 
429d8d19677SJose E. Roman    Input Parameters:
4305c6c1daeSBarry Smith +  bag - the bag of values
431*09cbc92aSBarry Smith .  addr - location of `PetscScalar` in struct, for example `&params->c`
4325c6c1daeSBarry Smith .  mdefault - the initial value
4335c6c1daeSBarry Smith .  name - name of the variable
4345c6c1daeSBarry Smith -  help - longer string with more information about the value
4355c6c1daeSBarry Smith 
4365c6c1daeSBarry Smith    Level: beginner
4375c6c1daeSBarry Smith 
438db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
439db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
440db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
4415c6c1daeSBarry Smith @*/
442d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help)
443d71ae5a4SJacob Faibussowitsch {
4445c6c1daeSBarry Smith   PetscBagItem item;
4455c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
4465c6c1daeSBarry Smith   PetscBool    printhelp;
4475c6c1daeSBarry Smith 
4485c6c1daeSBarry Smith   PetscFunctionBegin;
4495f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4505f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4515f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
4525f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
4535c6c1daeSBarry Smith   nname[0] = '-';
4545c6c1daeSBarry Smith   nname[1] = 0;
4559566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
4569566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
45748a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%g + %gi>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)PetscRealPart(mdefault), (double)PetscImaginaryPart(mdefault), help));
4589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL));
4595c6c1daeSBarry Smith 
4609566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
4615c6c1daeSBarry Smith   item->dtype  = PETSC_SCALAR;
4625c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
4635f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
46402c9f0b5SLisandro Dalcin   item->next           = NULL;
4655c6c1daeSBarry Smith   item->msize          = 1;
4665c6c1daeSBarry Smith   *(PetscScalar *)addr = mdefault;
4679566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
4683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4695c6c1daeSBarry Smith }
4705c6c1daeSBarry Smith 
4715c6c1daeSBarry Smith /*@C
472811af0c4SBarry Smith    PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`
4735c6c1daeSBarry Smith 
474c3339decSBarry Smith    Logically Collective
4755c6c1daeSBarry Smith 
476d8d19677SJose E. Roman    Input Parameters:
4775c6c1daeSBarry Smith +  bag - the bag of values
478*09cbc92aSBarry Smith .  addr - location of `PetscBool` in struct, for example `&params->b`
479811af0c4SBarry Smith .  mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
4805c6c1daeSBarry Smith .  name - name of the variable
4815c6c1daeSBarry Smith -  help - longer string with more information about the value
4825c6c1daeSBarry Smith 
4835c6c1daeSBarry Smith    Level: beginner
4845c6c1daeSBarry Smith 
485db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
486db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
487db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
4885c6c1daeSBarry Smith @*/
489d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help)
490d71ae5a4SJacob Faibussowitsch {
4915c6c1daeSBarry Smith   PetscBagItem item;
4925c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
4935c6c1daeSBarry Smith   PetscBool    printhelp;
4945c6c1daeSBarry Smith 
4955c6c1daeSBarry Smith   PetscFunctionBegin;
4965f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4975f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4985f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
4995f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
5005c6c1daeSBarry Smith   /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
5015f80ce2aSJacob Faibussowitsch   PetscCheck(mdefault == PETSC_FALSE || mdefault == PETSC_TRUE, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Boolean %s %s must be boolean; integer value %d", name, help, (int)mdefault);
5025c6c1daeSBarry Smith   nname[0] = '-';
5035c6c1daeSBarry Smith   nname[1] = 0;
5049566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
5059566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
50648a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help));
5079566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL));
5085c6c1daeSBarry Smith 
5099566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
5105c6c1daeSBarry Smith   item->dtype  = PETSC_BOOL;
5115c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
5125f80ce2aSJacob Faibussowitsch   PetscCheck(item->offset <= bag->bagsize, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Registered item %s %s is not in bag memory space", name, help);
51302c9f0b5SLisandro Dalcin   item->next         = NULL;
5145c6c1daeSBarry Smith   item->msize        = 1;
5155c6c1daeSBarry Smith   *(PetscBool *)addr = mdefault;
5169566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
5173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5185c6c1daeSBarry Smith }
5195c6c1daeSBarry Smith 
5205c6c1daeSBarry Smith /*@C
521811af0c4SBarry Smith    PetscBagDestroy - Destroys a `PetscBag`
5225c6c1daeSBarry Smith 
523c3339decSBarry Smith    Collective
5245c6c1daeSBarry Smith 
5255c6c1daeSBarry Smith    Input Parameter:
5265c6c1daeSBarry Smith .  bag - the bag of values
5275c6c1daeSBarry Smith 
5285c6c1daeSBarry Smith    Level: beginner
5295c6c1daeSBarry Smith 
530db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
531db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
532db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
5335c6c1daeSBarry Smith @*/
534d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagDestroy(PetscBag *bag)
535d71ae5a4SJacob Faibussowitsch {
5365f80ce2aSJacob Faibussowitsch   PetscBagItem nitem;
5375c6c1daeSBarry Smith 
5385c6c1daeSBarry Smith   PetscFunctionBegin;
5393ba16761SJacob Faibussowitsch   if (!*bag) PetscFunctionReturn(PETSC_SUCCESS);
5405f80ce2aSJacob Faibussowitsch   PetscValidPointer(*bag, 1);
5415f80ce2aSJacob Faibussowitsch   nitem = (*bag)->bagitems;
5425c6c1daeSBarry Smith   while (nitem) {
5435f80ce2aSJacob Faibussowitsch     PetscBagItem item = nitem->next;
5445f80ce2aSJacob Faibussowitsch 
5459566063dSJacob Faibussowitsch     if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list));
5469566063dSJacob Faibussowitsch     PetscCall(PetscFree(nitem));
5475c6c1daeSBarry Smith     nitem = item;
5485c6c1daeSBarry Smith   }
5499566063dSJacob Faibussowitsch   if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix));
5509566063dSJacob Faibussowitsch   PetscCall(PetscFree(*bag));
5513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5525c6c1daeSBarry Smith }
5535c6c1daeSBarry Smith 
5545c6c1daeSBarry Smith /*@
555811af0c4SBarry Smith    PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database
5565c6c1daeSBarry Smith 
557c3339decSBarry Smith    Collective
5585c6c1daeSBarry Smith 
5595c6c1daeSBarry Smith    Input Parameter:
5605c6c1daeSBarry Smith .  bag - the bag of values
5615c6c1daeSBarry Smith 
5625c6c1daeSBarry Smith    Level: beginner
5635c6c1daeSBarry Smith 
564811af0c4SBarry Smith    Note:
565811af0c4SBarry Smith    The options database keys for the entries are of the form `-[bagprefix]_name value`
566811af0c4SBarry Smith 
567db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
568db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
569db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()`
5705c6c1daeSBarry Smith @*/
571d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
572d71ae5a4SJacob Faibussowitsch {
5735c6c1daeSBarry Smith   PetscBagItem nitem = bag->bagitems;
5745c6c1daeSBarry Smith   char         name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3];
5755c6c1daeSBarry Smith   PetscInt     n;
5765c6c1daeSBarry Smith 
5775c6c1daeSBarry Smith   PetscFunctionBegin;
5785f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
5799566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname)));
5809566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname)));
5819566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname)));
582d0609cedSBarry Smith   PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL);
5835c6c1daeSBarry Smith   while (nitem) {
5845c6c1daeSBarry Smith     name[0] = '-';
5855c6c1daeSBarry Smith     name[1] = 0;
5869566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(name, nitem->name, sizeof(name)));
5875c6c1daeSBarry Smith     if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
5885c6c1daeSBarry Smith       char *value = (char *)(((char *)bag) + nitem->offset);
5899566063dSJacob Faibussowitsch       PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL));
5905c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_REAL) {
5915c6c1daeSBarry Smith       PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
5925c6c1daeSBarry Smith       if (nitem->msize == 1) {
5939566063dSJacob Faibussowitsch         PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL));
5945c6c1daeSBarry Smith       } else {
5955c6c1daeSBarry Smith         n = nitem->msize;
5969566063dSJacob Faibussowitsch         PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL));
5975c6c1daeSBarry Smith       }
5985c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_SCALAR) {
5995c6c1daeSBarry Smith       PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset);
6009566063dSJacob Faibussowitsch       PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL));
6015c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_INT) {
6025c6c1daeSBarry Smith       PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset);
6035c6c1daeSBarry Smith       if (nitem->msize == 1) {
6049566063dSJacob Faibussowitsch         PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL));
6055c6c1daeSBarry Smith       } else {
6065c6c1daeSBarry Smith         n = nitem->msize;
6079566063dSJacob Faibussowitsch         PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL));
6085c6c1daeSBarry Smith       }
6095c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_ENUM) {
6105c6c1daeSBarry Smith       PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset);
6115c6c1daeSBarry Smith       PetscInt   i     = 0;
6129371c9d4SSatish Balay       while (nitem->list[i++])
6139371c9d4SSatish Balay         ;
6149566063dSJacob Faibussowitsch       PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL));
6155c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_BOOL) {
6165c6c1daeSBarry Smith       PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
617dd66f111SBlaise Bourdin       if (nitem->msize == 1) {
6189566063dSJacob Faibussowitsch         PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL));
619dd66f111SBlaise Bourdin       } else {
620dd66f111SBlaise Bourdin         n = nitem->msize;
6219566063dSJacob Faibussowitsch         PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL));
622dd66f111SBlaise Bourdin       }
6235c6c1daeSBarry Smith     }
6245c6c1daeSBarry Smith     nitem = nitem->next;
6255c6c1daeSBarry Smith   }
626d0609cedSBarry Smith   PetscOptionsEnd();
6273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6285c6c1daeSBarry Smith }
6295c6c1daeSBarry Smith 
6305c6c1daeSBarry Smith /*@C
6315c6c1daeSBarry Smith    PetscBagView - Views a bag of values as either ASCII text or a binary file
6325c6c1daeSBarry Smith 
633c3339decSBarry Smith    Collective
6345c6c1daeSBarry Smith 
635d8d19677SJose E. Roman    Input Parameters:
6365c6c1daeSBarry Smith +  bag - the bag of values
6375c6c1daeSBarry Smith -  viewer - location to view the values
6385c6c1daeSBarry Smith 
6395c6c1daeSBarry Smith    Level: beginner
6405c6c1daeSBarry Smith 
641811af0c4SBarry Smith    Note:
642811af0c4SBarry Smith    Currently PETSc bags saved in a binary file can only be read back
643*09cbc92aSBarry Smith    in on a machine with the same binary format.
6445c6c1daeSBarry Smith 
645db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
646db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
647db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
6485c6c1daeSBarry Smith @*/
649d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view)
650d71ae5a4SJacob Faibussowitsch {
6515c6c1daeSBarry Smith   PetscBool    isascii, isbinary;
6525c6c1daeSBarry Smith   PetscBagItem nitem = bag->bagitems;
6535c6c1daeSBarry Smith 
6545c6c1daeSBarry Smith   PetscFunctionBegin;
6555f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
6565f80ce2aSJacob Faibussowitsch   PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2);
6579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii));
6589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
6595c6c1daeSBarry Smith   if (isascii) {
6603ffde785SBarry Smith     if (bag->bagprefix) {
6619566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object:  %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp));
6623ffde785SBarry Smith     } else {
6639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object:  %s %s\n", bag->bagname, bag->baghelp));
6643ffde785SBarry Smith     }
6655c6c1daeSBarry Smith     while (nitem) {
6665c6c1daeSBarry Smith       if (nitem->dtype == PETSC_CHAR) {
6675c6c1daeSBarry Smith         char *value             = (char *)(((char *)bag) + nitem->offset);
668da81f932SPierre Jolivet         char  tmp               = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */
6695c6c1daeSBarry Smith         value[nitem->msize - 1] = 0;
6709566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %s; %s\n", nitem->name, value, nitem->help));
6715c6c1daeSBarry Smith         value[nitem->msize - 1] = tmp;
6725c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_REAL) {
6735c6c1daeSBarry Smith         PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
6745c6c1daeSBarry Smith         PetscInt   i;
6759566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
67648a46eb9SPierre Jolivet         for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i]));
6779566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
6785c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_SCALAR) {
6795c6c1daeSBarry Smith         PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset);
6805c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
6818627564fSBarry Smith         if ((double)PetscImaginaryPart(value)) {
6829566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help));
6838627564fSBarry Smith         } else {
6849566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help));
6858627564fSBarry Smith         }
6865c6c1daeSBarry Smith #else
6879566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)value, nitem->help));
6885c6c1daeSBarry Smith #endif
6895c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_INT) {
6905c6c1daeSBarry Smith         PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset);
6919566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
69248a46eb9SPierre Jolivet         for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i]));
6939566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
6945c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_BOOL) {
695dd66f111SBlaise Bourdin         PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
696dd66f111SBlaise Bourdin         PetscInt   i;
6975c6c1daeSBarry Smith         /* some Fortran compilers use -1 as boolean */
6989566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
699dd66f111SBlaise Bourdin         for (i = 0; i < nitem->msize; i++) {
700dd66f111SBlaise Bourdin           if (((int)value[i]) == -1) value[i] = PETSC_TRUE;
7015c6c1daeSBarry Smith           /* the checks here with != PETSC_FALSE and PETSC_TRUE is a special case; here we truly demand that the value be 0 or 1 */
7025f80ce2aSJacob Faibussowitsch           PetscCheck(value[i] == PETSC_FALSE || value[i] == PETSC_TRUE, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Boolean value for %s %s is corrupt; integer value %" PetscInt_FMT, nitem->name, nitem->help, (PetscInt)(value[i]));
7039566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]]));
704dd66f111SBlaise Bourdin         }
7059566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
7065c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_ENUM) {
7075c6c1daeSBarry Smith         PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset);
7085c6c1daeSBarry Smith         PetscInt  i     = 0;
7099371c9d4SSatish Balay         while (nitem->list[i++])
7109371c9d4SSatish Balay           ;
7119566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help));
7125c6c1daeSBarry Smith       }
7135c6c1daeSBarry Smith       nitem = nitem->next;
7145c6c1daeSBarry Smith     }
7155c6c1daeSBarry Smith   } else if (isbinary) {
7165c6c1daeSBarry Smith     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
7175c6c1daeSBarry Smith     PetscInt          deprecatedbagsize = 0;
718a261c58fSBarry Smith     PetscViewerFormat format;
7199566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT));
7209566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT));
7219566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT));
7229566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
7239566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
7245c6c1daeSBarry Smith     while (nitem) {
7259566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT));
7265c6c1daeSBarry Smith       dtype = (PetscInt)nitem->dtype;
7279566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT));
7289566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
7299566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
7309566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT));
7315c6c1daeSBarry Smith       /* some Fortran compilers use -1 as boolean */
7325c6c1daeSBarry Smith       if (dtype == PETSC_BOOL && ((*(int *)(((char *)bag) + nitem->offset) == -1))) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE;
7335c6c1daeSBarry Smith 
7349566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, (((char *)bag) + nitem->offset), nitem->msize, nitem->dtype));
73548a46eb9SPierre Jolivet       if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list));
7365c6c1daeSBarry Smith       nitem = nitem->next;
7375c6c1daeSBarry Smith     }
7389566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(view, &format));
739a261c58fSBarry Smith     if (format == PETSC_VIEWER_BINARY_MATLAB) {
740a261c58fSBarry Smith       MPI_Comm comm;
741a261c58fSBarry Smith       FILE    *info;
7429566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
7439566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetInfoPointer(view, &info));
7449566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n"));
7459566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname));
7469566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n"));
747a261c58fSBarry Smith     }
748a261c58fSBarry Smith   }
7493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7505c6c1daeSBarry Smith }
7515c6c1daeSBarry Smith 
7525c6c1daeSBarry Smith /*@C
753*09cbc92aSBarry Smith   PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed.
754173f9484SMatthew G. Knepley 
755c3339decSBarry Smith   Collective
756173f9484SMatthew G. Knepley 
757173f9484SMatthew G. Knepley   Input Parameters:
758173f9484SMatthew G. Knepley + obj   - the object
759*09cbc92aSBarry Smith . bobj  - optional other object that provides prefix (if `NULL` then the prefix in obj is used)
760173f9484SMatthew G. Knepley - optionname - option to activate viewing
761478db826SMatthew G. Knepley 
762173f9484SMatthew G. Knepley   Level: intermediate
763478db826SMatthew G. Knepley 
764db781477SPatrick Sanan .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer`
765173f9484SMatthew G. Knepley @*/
766d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[])
767d71ae5a4SJacob Faibussowitsch {
768173f9484SMatthew G. Knepley   static PetscBool  incall = PETSC_FALSE;
769173f9484SMatthew G. Knepley   PetscViewer       viewer;
770173f9484SMatthew G. Knepley   PetscViewerFormat format;
771173f9484SMatthew G. Knepley   const char       *prefix, *bprefix = NULL;
772173f9484SMatthew G. Knepley   PetscBool         flg;
773173f9484SMatthew G. Knepley 
774173f9484SMatthew G. Knepley   PetscFunctionBegin;
7753ba16761SJacob Faibussowitsch   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
776173f9484SMatthew G. Knepley   incall = PETSC_TRUE;
7775f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
7789566063dSJacob Faibussowitsch   if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix));
779173f9484SMatthew G. Knepley   prefix = bobj ? bprefix : bag->bagprefix;
7809566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg));
781173f9484SMatthew G. Knepley   if (flg) {
7829566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
7839566063dSJacob Faibussowitsch     PetscCall(PetscBagView(bag, viewer));
7849566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
7859566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
7869566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
787173f9484SMatthew G. Knepley   }
788173f9484SMatthew G. Knepley   incall = PETSC_FALSE;
7893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
790173f9484SMatthew G. Knepley }
791173f9484SMatthew G. Knepley 
792173f9484SMatthew G. Knepley /*@C
7935c6c1daeSBarry Smith    PetscBagLoad - Loads a bag of values from a binary file
7945c6c1daeSBarry Smith 
795c3339decSBarry Smith    Collective
7965c6c1daeSBarry Smith 
797d8d19677SJose E. Roman    Input Parameters:
7985c6c1daeSBarry Smith +  viewer - file to load values from
7995c6c1daeSBarry Smith -  bag - the bag of values
8005c6c1daeSBarry Smith 
8015c6c1daeSBarry Smith    Level: beginner
8025c6c1daeSBarry Smith 
803*09cbc92aSBarry Smith    Note:
804*09cbc92aSBarry Smith     You must have created and registered all the fields in the bag before loading into it. This only loads values.
805*09cbc92aSBarry Smith 
806db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()`
807db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
808db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
8095c6c1daeSBarry Smith @*/
810d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag)
811d71ae5a4SJacob Faibussowitsch {
8125c6c1daeSBarry Smith   PetscBool    isbinary;
8135f80ce2aSJacob Faibussowitsch   PetscInt     classid, bagcount, dtype, msize, offset, deprecatedbagsize;
8145c6c1daeSBarry Smith   char         name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list;
8155c6c1daeSBarry Smith   PetscBagItem nitem;
8165c6c1daeSBarry Smith   MPI_Comm     comm;
8175c6c1daeSBarry Smith   PetscMPIInt  flag;
8185c6c1daeSBarry Smith 
8195c6c1daeSBarry Smith   PetscFunctionBegin;
8205f80ce2aSJacob Faibussowitsch   PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1);
8215f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 2);
8229566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
8239566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag));
8245f80ce2aSJacob Faibussowitsch   PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag");
8259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
8265f80ce2aSJacob Faibussowitsch   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type");
8275c6c1daeSBarry Smith 
8289566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT));
8295f80ce2aSJacob Faibussowitsch   PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file");
8309566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT));
8319566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT));
8325f80ce2aSJacob Faibussowitsch   PetscCheck(bagcount == bag->count, comm, PETSC_ERR_ARG_INCOMP, "Bag in file has different number of entries %d then passed in bag %d", (int)bagcount, (int)bag->count);
8339566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
8349566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
8355c6c1daeSBarry Smith 
8365c6c1daeSBarry Smith   nitem = bag->bagitems;
8375f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < bagcount; i++) {
8389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT));
8395c6c1daeSBarry Smith     /* ignore the offset in the file */
8409566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT));
8419566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
8429566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
8439566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT));
8445c6c1daeSBarry Smith 
8455c6c1daeSBarry Smith     if (dtype == (PetscInt)PETSC_CHAR) {
8469566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR));
8475c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_REAL) {
8489566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL));
8495c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_SCALAR) {
8509566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR));
8515c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_INT) {
8529566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT));
8535c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_BOOL) {
8549566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL));
8555c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_ENUM) {
8569566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM));
8579566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryReadStringArray(view, &list));
8585c6c1daeSBarry Smith       /* don't need to save list because it is already registered in the bag */
8599566063dSJacob Faibussowitsch       PetscCall(PetscFree(list));
8605c6c1daeSBarry Smith     }
8615c6c1daeSBarry Smith     nitem = nitem->next;
8625c6c1daeSBarry Smith   }
8633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8645c6c1daeSBarry Smith }
8655c6c1daeSBarry Smith 
866e8976759SBarry Smith /*@C
867*09cbc92aSBarry Smith     PetscBagCreate - Create a bag of values. A `PetscBag` is a representation of a C struct that can be saved to and read from files,
868*09cbc92aSBarry Smith     can have values set from the options database
8695c6c1daeSBarry Smith 
870d083f849SBarry Smith   Collective
8715c6c1daeSBarry Smith 
8725c6c1daeSBarry Smith   Input Parameters:
8735c6c1daeSBarry Smith +  comm - communicator to share bag
874811af0c4SBarry Smith -  bagsize - size of the C structure holding the values, for example sizeof(mystruct)
8755c6c1daeSBarry Smith 
8765c6c1daeSBarry Smith   Output Parameter:
8775c6c1daeSBarry Smith .   bag - the bag of values
8785c6c1daeSBarry Smith 
879*09cbc92aSBarry Smith   Level: Intermediate
880*09cbc92aSBarry Smith 
8815c6c1daeSBarry Smith    Notes:
882811af0c4SBarry Smith    After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout
883811af0c4SBarry Smith 
884811af0c4SBarry Smith    The size of the A struct must be small enough to fit in a `PetscInt`; by default
885811af0c4SBarry Smith    `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
8865c6c1daeSBarry Smith    The warning about casting to a shorter length can be ignored below unless your A struct is too large
8875c6c1daeSBarry Smith 
888db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
889db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
890db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
8915c6c1daeSBarry Smith @*/
892d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
893d71ae5a4SJacob Faibussowitsch {
8945f80ce2aSJacob Faibussowitsch   const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar);
8955c6c1daeSBarry Smith 
8965c6c1daeSBarry Smith   PetscFunctionBegin;
8975f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 3);
8989566063dSJacob Faibussowitsch   PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize));
8999566063dSJacob Faibussowitsch   PetscCall(PetscCalloc(totalsize, bag));
900a297a907SKarl Rupp 
9015f80ce2aSJacob Faibussowitsch   (*bag)->bagsize        = totalsize;
9025c6c1daeSBarry Smith   (*bag)->bagcomm        = comm;
9030298fd71SBarry Smith   (*bag)->bagprefix      = NULL;
9045c6c1daeSBarry Smith   (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar));
9053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9065c6c1daeSBarry Smith }
9075c6c1daeSBarry Smith 
9085c6c1daeSBarry Smith /*@C
9095c6c1daeSBarry Smith     PetscBagSetName - Sets the name of a bag of values
9105c6c1daeSBarry Smith 
9115c6c1daeSBarry Smith   Not Collective
9125c6c1daeSBarry Smith 
9135c6c1daeSBarry Smith   Level: Intermediate
9145c6c1daeSBarry Smith 
9155c6c1daeSBarry Smith   Input Parameters:
9165c6c1daeSBarry Smith +   bag - the bag of values
9175c6c1daeSBarry Smith .   name - the name assigned to the bag
9185c6c1daeSBarry Smith -   help - help message for bag
9195c6c1daeSBarry Smith 
920db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
921db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
922db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9235c6c1daeSBarry Smith @*/
924d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
925d71ae5a4SJacob Faibussowitsch {
9265c6c1daeSBarry Smith   PetscFunctionBegin;
9275f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9285f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 2);
9295f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 3);
9309566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1));
9319566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1));
9323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9335c6c1daeSBarry Smith }
9345c6c1daeSBarry Smith 
9355c6c1daeSBarry Smith /*@C
9365c6c1daeSBarry Smith     PetscBagGetName - Gets the name of a bag of values
9375c6c1daeSBarry Smith 
9385c6c1daeSBarry Smith   Not Collective
9395c6c1daeSBarry Smith 
9405c6c1daeSBarry Smith   Level: Intermediate
9415c6c1daeSBarry Smith 
9425c6c1daeSBarry Smith   Input Parameter:
9435c6c1daeSBarry Smith .   bag - the bag of values
9445c6c1daeSBarry Smith 
9455c6c1daeSBarry Smith   Output Parameter:
9465c6c1daeSBarry Smith .   name - the name assigned to the bag
9475c6c1daeSBarry Smith 
948db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
949db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
950db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9515c6c1daeSBarry Smith @*/
952d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
953d71ae5a4SJacob Faibussowitsch {
9545c6c1daeSBarry Smith   PetscFunctionBegin;
9555f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9565f80ce2aSJacob Faibussowitsch   PetscValidPointer(name, 2);
9575c6c1daeSBarry Smith   *name = bag->bagname;
9583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9595c6c1daeSBarry Smith }
9605c6c1daeSBarry Smith 
9615c6c1daeSBarry Smith /*@C
9625c6c1daeSBarry Smith     PetscBagGetData - Gives back the user - access to memory that
963811af0c4SBarry Smith     can be used for storing user-data-structure
9645c6c1daeSBarry Smith 
9655c6c1daeSBarry Smith   Not Collective
9665c6c1daeSBarry Smith 
9675c6c1daeSBarry Smith   Input Parameter:
9685c6c1daeSBarry Smith .   bag - the bag of values
9695c6c1daeSBarry Smith 
9705c6c1daeSBarry Smith   Output Parameter:
971*09cbc92aSBarry Smith .   data - pointer to memory that will have user-data-structure, this can be cast to a pointer of the type the C struct used in
972*09cbc92aSBarry Smith     defining the bag
973*09cbc92aSBarry Smith 
974*09cbc92aSBarry Smith   Level: Intermediate
9755c6c1daeSBarry Smith 
976db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`
977db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
978db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9795c6c1daeSBarry Smith @*/
980d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
981d71ae5a4SJacob Faibussowitsch {
9825c6c1daeSBarry Smith   PetscFunctionBegin;
9835f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9845f80ce2aSJacob Faibussowitsch   PetscValidPointer(data, 2);
9855c6c1daeSBarry Smith   *data = bag->structlocation;
9863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9875c6c1daeSBarry Smith }
9885c6c1daeSBarry Smith 
9895c6c1daeSBarry Smith /*@C
9905c6c1daeSBarry Smith   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
991811af0c4SBarry Smith   `PetscBag` items in the options database.
9925c6c1daeSBarry Smith 
993*09cbc92aSBarry Smith   Logically Collective
9945c6c1daeSBarry Smith 
9955c6c1daeSBarry Smith   Level: Intermediate
9965c6c1daeSBarry Smith 
9975c6c1daeSBarry Smith   Input Parameters:
9985c6c1daeSBarry Smith +   bag - the bag of values
9995c6c1daeSBarry Smith -   prefix - the prefix to prepend all Bag item names with.
10005c6c1daeSBarry Smith 
1001*09cbc92aSBarry Smith   Note:
1002*09cbc92aSBarry Smith   Must be called prior to registering any of the bag items.
10035c6c1daeSBarry Smith 
1004db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
1005db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
10065c6c1daeSBarry Smith @*/
10075c6c1daeSBarry Smith 
1008d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1009d71ae5a4SJacob Faibussowitsch {
10105c6c1daeSBarry Smith   PetscFunctionBegin;
10115f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
10125f80ce2aSJacob Faibussowitsch   if (pre) {
10135f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(pre, 2);
10145f80ce2aSJacob Faibussowitsch     PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen");
10159566063dSJacob Faibussowitsch     PetscCall(PetscFree(bag->bagprefix));
10169566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(pre, &(bag->bagprefix)));
10179566063dSJacob Faibussowitsch   } else PetscCall(PetscFree(bag->bagprefix));
10183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10195c6c1daeSBarry Smith }
1020ffb7e86cSMatthew G. Knepley 
1021ffb7e86cSMatthew G. Knepley /*@C
1022ffb7e86cSMatthew G. Knepley   PetscBagGetNames - Get the names of all entries in the bag
1023ffb7e86cSMatthew G. Knepley 
1024*09cbc92aSBarry Smith   Not Collective
1025ffb7e86cSMatthew G. Knepley 
1026ffb7e86cSMatthew G. Knepley   Input Parameters:
1027ffb7e86cSMatthew G. Knepley + bag   - the bag of values
1028811af0c4SBarry Smith - names - array of the correct size to hold names, must be long enough to hold all the names
1029ffb7e86cSMatthew G. Knepley 
1030ffb7e86cSMatthew G. Knepley   Output Parameter:
1031ffb7e86cSMatthew G. Knepley . names - array of char pointers for names
1032ffb7e86cSMatthew G. Knepley 
1033ffb7e86cSMatthew G. Knepley   Level: intermediate
1034ffb7e86cSMatthew G. Knepley 
1035db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagSetName()`, `PetscBagCreate()`, `PetscBagGetData()`
1036db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
1037ffb7e86cSMatthew G. Knepley @*/
1038d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagGetNames(PetscBag bag, const char *names[])
1039d71ae5a4SJacob Faibussowitsch {
1040ffb7e86cSMatthew G. Knepley   PetscBagItem nitem = bag->bagitems;
1041ffb7e86cSMatthew G. Knepley 
1042ffb7e86cSMatthew G. Knepley   PetscFunctionBegin;
10435f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
10445f80ce2aSJacob Faibussowitsch   PetscValidPointer(names, 2);
10455f80ce2aSJacob Faibussowitsch   for (PetscInt n = 0; nitem; ++n, nitem = nitem->next) names[n] = nitem->name;
10463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1047ffb7e86cSMatthew G. Knepley }
1048