xref: /petsc/src/sys/classes/bag/bag.c (revision 2fe279fdf3e687a416e4eadb7d3c7a82d60442c6)
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`)
33*2fe279fdSBarry Smith .  name - the name of the item
345c6c1daeSBarry Smith -  help - longer string with more information about the value
355c6c1daeSBarry Smith 
365c6c1daeSBarry Smith    Level: beginner
375c6c1daeSBarry Smith 
38db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
39db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
40db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
415c6c1daeSBarry Smith @*/
42d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterEnum(PetscBag bag, void *addr, const char *const *list, PetscEnum mdefault, const char *name, const char *help)
43d71ae5a4SJacob Faibussowitsch {
445c6c1daeSBarry Smith   PetscBagItem item;
455c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
465c6c1daeSBarry Smith   PetscBool    printhelp;
475c6c1daeSBarry Smith   PetscInt     i = 0;
485c6c1daeSBarry Smith 
495c6c1daeSBarry Smith   PetscFunctionBegin;
505f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
515f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
525f80ce2aSJacob Faibussowitsch   PetscValidPointer(list, 3);
535f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 5);
545f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 6);
555c6c1daeSBarry Smith   nname[0] = '-';
565c6c1daeSBarry Smith   nname[1] = 0;
579566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
589566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
595c6c1daeSBarry Smith   if (printhelp) {
609371c9d4SSatish Balay     while (list[i++])
619371c9d4SSatish Balay       ;
629566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: (%s) %s (choose one of) ", bag->bagprefix ? bag->bagprefix : "", name, list[mdefault], list[i - 3], help));
639566063dSJacob Faibussowitsch     for (i = 0; list[i + 2]; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, " %s", list[i]));
649566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "\n"));
655c6c1daeSBarry Smith   }
669566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetEnum(NULL, bag->bagprefix, nname, list, &mdefault, NULL));
675c6c1daeSBarry Smith 
689566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
695c6c1daeSBarry Smith   item->dtype  = PETSC_ENUM;
705c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
715f80ce2aSJacob 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);
7202c9f0b5SLisandro Dalcin   item->next  = NULL;
735c6c1daeSBarry Smith   item->msize = 1;
749566063dSJacob Faibussowitsch   PetscCall(PetscStrArrayallocpy(list, (char ***)&item->list));
755c6c1daeSBarry Smith   *(PetscEnum *)addr = mdefault;
769566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
785c6c1daeSBarry Smith }
795c6c1daeSBarry Smith 
805c6c1daeSBarry Smith /*@C
8109cbc92aSBarry Smith    PetscBagRegisterIntArray - add a `PetscInt` array to a `PetscBag`
825c6c1daeSBarry Smith 
83c3339decSBarry Smith    Logically Collective
845c6c1daeSBarry Smith 
85d8d19677SJose E. Roman    Input Parameters:
865c6c1daeSBarry Smith +  bag - the bag of values
87811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
885c6c1daeSBarry Smith .  msize - number of entries in array
89811af0c4SBarry Smith .  name - name of the array
905c6c1daeSBarry Smith -  help - longer string with more information about the value
915c6c1daeSBarry Smith 
925c6c1daeSBarry Smith    Level: beginner
935c6c1daeSBarry Smith 
94db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
95db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
96db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
975c6c1daeSBarry Smith @*/
98d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterIntArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
99d71ae5a4SJacob Faibussowitsch {
1005c6c1daeSBarry Smith   PetscBagItem item;
1015c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
1025c6c1daeSBarry Smith   PetscBool    printhelp;
1035c6c1daeSBarry Smith   PetscInt     i, tmp = msize;
1045c6c1daeSBarry Smith 
1055c6c1daeSBarry Smith   PetscFunctionBegin;
1065f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
1075f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
1085f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
1095f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
1105c6c1daeSBarry Smith   nname[0] = '-';
1115c6c1daeSBarry Smith   nname[1] = 0;
1129566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
1139566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
1145c6c1daeSBarry Smith   if (printhelp) {
1159566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
11648a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i));
1179566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
1185c6c1daeSBarry Smith   }
1199566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetIntArray(NULL, bag->bagprefix, nname, (PetscInt *)addr, &tmp, NULL));
1205c6c1daeSBarry Smith 
1219566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
1225c6c1daeSBarry Smith   item->dtype  = PETSC_INT;
1235c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
1245f80ce2aSJacob 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);
12502c9f0b5SLisandro Dalcin   item->next  = NULL;
1265c6c1daeSBarry Smith   item->msize = msize;
1279566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
1283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1295c6c1daeSBarry Smith }
1305c6c1daeSBarry Smith 
1315c6c1daeSBarry Smith /*@C
13209cbc92aSBarry Smith    PetscBagRegisterRealArray - add a `PetscReal` array to a `PetscBag`
1335c6c1daeSBarry Smith 
134c3339decSBarry Smith    Logically Collective
1355c6c1daeSBarry Smith 
136d8d19677SJose E. Roman    Input Parameters:
1375c6c1daeSBarry Smith +  bag - the bag of values
138811af0c4SBarry Smith .  addr - location of real array in struct, for example `&params->d`
139811af0c4SBarry Smith .  msize - number of entries in the array
140811af0c4SBarry Smith .  name - name of the array
1415c6c1daeSBarry Smith -  help - longer string with more information about the value
1425c6c1daeSBarry Smith 
1435c6c1daeSBarry Smith    Level: beginner
1445c6c1daeSBarry Smith 
145db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
146db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
147db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
1485c6c1daeSBarry Smith @*/
149d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterRealArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
150d71ae5a4SJacob Faibussowitsch {
1515c6c1daeSBarry Smith   PetscBagItem item;
1525c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
1535c6c1daeSBarry Smith   PetscBool    printhelp;
1545c6c1daeSBarry Smith   PetscInt     i, tmp = msize;
1555c6c1daeSBarry Smith 
1565c6c1daeSBarry Smith   PetscFunctionBegin;
1575f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
1585f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
1595f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
1605f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
1615c6c1daeSBarry Smith   nname[0] = '-';
1625c6c1daeSBarry Smith   nname[1] = 0;
1639566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
1649566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
1655c6c1daeSBarry Smith   if (printhelp) {
1669566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
16748a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%g ", (double)*((PetscReal *)addr) + i));
1689566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
1695c6c1daeSBarry Smith   }
1709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetRealArray(NULL, bag->bagprefix, nname, (PetscReal *)addr, &tmp, NULL));
1715c6c1daeSBarry Smith 
1729566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
1735c6c1daeSBarry Smith   item->dtype  = PETSC_REAL;
1745c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
1755f80ce2aSJacob 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);
17602c9f0b5SLisandro Dalcin   item->next  = NULL;
1775c6c1daeSBarry Smith   item->msize = msize;
1789566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
1793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1805c6c1daeSBarry Smith }
1815c6c1daeSBarry Smith 
1825c6c1daeSBarry Smith /*@C
18309cbc92aSBarry Smith    PetscBagRegisterInt - add a `PetscInt` value to a `PetscBag`
1845c6c1daeSBarry Smith 
185c3339decSBarry Smith    Logically Collective
1865c6c1daeSBarry Smith 
187d8d19677SJose E. Roman    Input Parameters:
1885c6c1daeSBarry Smith +  bag - the bag of values
189811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
1905c6c1daeSBarry Smith .  mdefault - the initial value
1915c6c1daeSBarry Smith .  name - name of the integer
1925c6c1daeSBarry Smith -  help - longer string with more information about the value
1935c6c1daeSBarry Smith 
1945c6c1daeSBarry Smith    Level: beginner
1955c6c1daeSBarry Smith 
196db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
197db781477SPatrick Sanan           `PetscBagRegisterInt64()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
198db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
1995c6c1daeSBarry Smith @*/
200d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterInt(PetscBag bag, void *addr, PetscInt mdefault, const char *name, const char *help)
201d71ae5a4SJacob Faibussowitsch {
2025c6c1daeSBarry Smith   PetscBagItem item;
2035c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
2045c6c1daeSBarry Smith   PetscBool    printhelp;
2055c6c1daeSBarry Smith 
2065c6c1daeSBarry Smith   PetscFunctionBegin;
2075f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
2085f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
2095f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
2105f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
2115c6c1daeSBarry Smith   nname[0] = '-';
2125c6c1daeSBarry Smith   nname[1] = 0;
2139566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
2149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
21548a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
2169566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &mdefault, NULL));
2175c6c1daeSBarry Smith 
2189566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
2195c6c1daeSBarry Smith   item->dtype  = PETSC_INT;
2205c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
2215f80ce2aSJacob 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);
22202c9f0b5SLisandro Dalcin   item->next        = NULL;
2235c6c1daeSBarry Smith   item->msize       = 1;
2245c6c1daeSBarry Smith   *(PetscInt *)addr = mdefault;
2259566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
2263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2275c6c1daeSBarry Smith }
2285c6c1daeSBarry Smith 
2290d349d43SBarry Smith /*@C
230811af0c4SBarry Smith    PetscBagRegisterInt64 - add a `PetscInt64` value to a `PetscBag`
2310d349d43SBarry Smith 
232c3339decSBarry Smith    Logically Collective
2330d349d43SBarry Smith 
234d8d19677SJose E. Roman    Input Parameters:
2350d349d43SBarry Smith +  bag - the bag of values
236811af0c4SBarry Smith .  addr - location of integer in struct, for example `&params->i`
2370d349d43SBarry Smith .  mdefault - the initial value
2380d349d43SBarry Smith .  name - name of the integer
2390d349d43SBarry Smith -  help - longer string with more information about the value
2400d349d43SBarry Smith 
2410d349d43SBarry Smith    Level: beginner
2420d349d43SBarry Smith 
243db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
244db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
245db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
2460d349d43SBarry Smith @*/
247d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterInt64(PetscBag bag, void *addr, PetscInt64 mdefault, const char *name, const char *help)
248d71ae5a4SJacob Faibussowitsch {
2490d349d43SBarry Smith   PetscBagItem item;
2500d349d43SBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
2510d349d43SBarry Smith   PetscBool    printhelp;
2520d349d43SBarry Smith   PetscInt     odefault = (PetscInt)mdefault;
2530d349d43SBarry Smith   PetscBool    flg;
2540d349d43SBarry Smith 
2550d349d43SBarry Smith   PetscFunctionBegin;
2560d349d43SBarry Smith   nname[0] = '-';
2570d349d43SBarry Smith   nname[1] = 0;
2589566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
2599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
26048a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%" PetscInt_FMT ">: %s \n", bag->bagprefix ? bag->bagprefix : "", name, odefault, help));
2619566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetInt(NULL, bag->bagprefix, nname, &odefault, &flg));
262bafee8b4SSatish Balay   if (flg) mdefault = (PetscInt64)odefault;
2630d349d43SBarry Smith 
2649566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
2650d349d43SBarry Smith   item->dtype  = PETSC_INT;
2660d349d43SBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
2675f80ce2aSJacob 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);
26802c9f0b5SLisandro Dalcin   item->next          = NULL;
2690d349d43SBarry Smith   item->msize         = 1;
270bafee8b4SSatish Balay   *(PetscInt64 *)addr = mdefault;
2719566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
2723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2730d349d43SBarry Smith }
2740d349d43SBarry Smith 
275dd66f111SBlaise Bourdin /*@C
276811af0c4SBarry Smith    PetscBagRegisterBoolArray - add a n `PetscBool` values to a `PetscBag`
277dd66f111SBlaise Bourdin 
278c3339decSBarry Smith    Logically Collective
279dd66f111SBlaise Bourdin 
280d8d19677SJose E. Roman    Input Parameters:
281dd66f111SBlaise Bourdin +  bag - the bag of values
282811af0c4SBarry Smith .  addr - location of boolean array in struct, for example `&params->b`
283dd66f111SBlaise Bourdin .  msize - number of entries in array
284dd66f111SBlaise Bourdin .  name - name of the boolean array
285dd66f111SBlaise Bourdin -  help - longer string with more information about the value
286dd66f111SBlaise Bourdin 
287dd66f111SBlaise Bourdin    Level: beginner
288dd66f111SBlaise Bourdin 
289db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
290db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
291db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
292dd66f111SBlaise Bourdin @*/
293d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterBoolArray(PetscBag bag, void *addr, PetscInt msize, const char *name, const char *help)
294d71ae5a4SJacob Faibussowitsch {
295dd66f111SBlaise Bourdin   PetscBagItem item;
296dd66f111SBlaise Bourdin   char         nname[PETSC_BAG_NAME_LENGTH + 1];
297dd66f111SBlaise Bourdin   PetscBool    printhelp;
298dd66f111SBlaise Bourdin   PetscInt     i, tmp = msize;
299dd66f111SBlaise Bourdin 
300dd66f111SBlaise Bourdin   PetscFunctionBegin;
3015f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
3025f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
3035f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
3045f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
305dd66f111SBlaise Bourdin   nname[0] = '-';
306dd66f111SBlaise Bourdin   nname[1] = 0;
3079566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
3089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
309dd66f111SBlaise Bourdin   if (printhelp) {
3109566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <", bag->bagprefix ? bag->bagprefix : "", name));
31148a46eb9SPierre Jolivet     for (i = 0; i < msize; i++) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "%" PetscInt_FMT " ", *((PetscInt *)addr) + i));
3129566063dSJacob Faibussowitsch     PetscCall((*PetscHelpPrintf)(bag->bagcomm, ">: %s \n", help));
313dd66f111SBlaise Bourdin   }
3149566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBoolArray(NULL, bag->bagprefix, nname, (PetscBool *)addr, &tmp, NULL));
315dd66f111SBlaise Bourdin 
3169566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
317dd66f111SBlaise Bourdin   item->dtype  = PETSC_BOOL;
318dd66f111SBlaise Bourdin   item->offset = ((char *)addr) - ((char *)bag);
3195f80ce2aSJacob 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);
32002c9f0b5SLisandro Dalcin   item->next  = NULL;
321dd66f111SBlaise Bourdin   item->msize = msize;
3229566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
3233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
324dd66f111SBlaise Bourdin }
325dd66f111SBlaise Bourdin 
3265c6c1daeSBarry Smith /*@C
327811af0c4SBarry Smith    PetscBagRegisterString - add a string value to a `PetscBag`
3285c6c1daeSBarry Smith 
329c3339decSBarry Smith    Logically Collective
3305c6c1daeSBarry Smith 
331d8d19677SJose E. Roman    Input Parameters:
3325c6c1daeSBarry Smith +  bag - the bag of values
333811af0c4SBarry Smith .  addr - location of start of string in struct, for example `&params->mystring`
3345c6c1daeSBarry Smith .  msize - length of the string space in the struct
3355c6c1daeSBarry Smith .  mdefault - the initial value
3365c6c1daeSBarry Smith .  name - name of the string
3375c6c1daeSBarry Smith -  help - longer string with more information about the value
3385c6c1daeSBarry Smith 
3395c6c1daeSBarry Smith    Level: beginner
3405c6c1daeSBarry Smith 
34109cbc92aSBarry Smith    Note:
34209cbc92aSBarry Smith    The struct must have the field char mystring[`msize`]; not char *mystring
3435c6c1daeSBarry Smith 
344db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
345db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
346c2e3fba1SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
3475c6c1daeSBarry Smith @*/
348d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterString(PetscBag bag, void *addr, PetscInt msize, const char *mdefault, const char *name, const char *help)
349d71ae5a4SJacob Faibussowitsch {
3505c6c1daeSBarry Smith   PetscBagItem item;
3515c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
3525c6c1daeSBarry Smith   PetscBool    printhelp;
3535c6c1daeSBarry Smith 
3545c6c1daeSBarry Smith   PetscFunctionBegin;
3555f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
3565f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
3575f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(mdefault, 4);
3585f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 5);
3595f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 6);
3605c6c1daeSBarry Smith   nname[0] = '-';
3615c6c1daeSBarry Smith   nname[1] = 0;
3629566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
3639566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
36448a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, mdefault, help));
3655c6c1daeSBarry Smith 
3669566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
3675c6c1daeSBarry Smith   item->dtype  = PETSC_CHAR;
3685c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
3695f80ce2aSJacob 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);
37002c9f0b5SLisandro Dalcin   item->next  = NULL;
3715c6c1daeSBarry Smith   item->msize = msize;
37248a46eb9SPierre Jolivet   if (mdefault != (char *)addr) PetscCall(PetscStrncpy((char *)addr, mdefault, msize - 1));
3739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetString(NULL, bag->bagprefix, nname, (char *)addr, msize, NULL));
3749566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
3753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3765c6c1daeSBarry Smith }
3775c6c1daeSBarry Smith 
3785c6c1daeSBarry Smith /*@C
379811af0c4SBarry Smith    PetscBagRegisterReal - add a `PetscReal` value to a `PetscBag`
3805c6c1daeSBarry Smith 
381c3339decSBarry Smith    Logically Collective
3825c6c1daeSBarry Smith 
383d8d19677SJose E. Roman    Input Parameters:
3845c6c1daeSBarry Smith +  bag - the bag of values
38509cbc92aSBarry Smith .  addr - location of `PetscReal` in struct, for example `&params->r`
3865c6c1daeSBarry Smith .  mdefault - the initial value
3875c6c1daeSBarry Smith .  name - name of the variable
3885c6c1daeSBarry Smith -  help - longer string with more information about the value
3895c6c1daeSBarry Smith 
3905c6c1daeSBarry Smith    Level: beginner
3915c6c1daeSBarry Smith 
392db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
393db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
394db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
3955c6c1daeSBarry Smith @*/
396d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterReal(PetscBag bag, void *addr, PetscReal mdefault, const char *name, const char *help)
397d71ae5a4SJacob Faibussowitsch {
3985c6c1daeSBarry Smith   PetscBagItem item;
3995c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
4005c6c1daeSBarry Smith   PetscBool    printhelp;
4015c6c1daeSBarry Smith 
4025c6c1daeSBarry Smith   PetscFunctionBegin;
4035f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4045f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4055f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
4065f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
4075c6c1daeSBarry Smith   nname[0] = '-';
4085c6c1daeSBarry Smith   nname[1] = 0;
4099566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
4109566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
41148a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%g>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, (double)mdefault, help));
4129566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetReal(NULL, bag->bagprefix, nname, &mdefault, NULL));
4135c6c1daeSBarry Smith 
4149566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
4155c6c1daeSBarry Smith   item->dtype  = PETSC_REAL;
4165c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
4175f80ce2aSJacob 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);
41802c9f0b5SLisandro Dalcin   item->next         = NULL;
4195c6c1daeSBarry Smith   item->msize        = 1;
4205c6c1daeSBarry Smith   *(PetscReal *)addr = mdefault;
4219566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
4223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4235c6c1daeSBarry Smith }
4245c6c1daeSBarry Smith 
4255c6c1daeSBarry Smith /*@C
426811af0c4SBarry Smith    PetscBagRegisterScalar - add a `PetscScalar` value to a `PetscBag`
4275c6c1daeSBarry Smith 
428c3339decSBarry Smith    Logically Collective
4295c6c1daeSBarry Smith 
430d8d19677SJose E. Roman    Input Parameters:
4315c6c1daeSBarry Smith +  bag - the bag of values
43209cbc92aSBarry Smith .  addr - location of `PetscScalar` in struct, for example `&params->c`
4335c6c1daeSBarry Smith .  mdefault - the initial value
4345c6c1daeSBarry Smith .  name - name of the variable
4355c6c1daeSBarry Smith -  help - longer string with more information about the value
4365c6c1daeSBarry Smith 
4375c6c1daeSBarry Smith    Level: beginner
4385c6c1daeSBarry Smith 
439db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
440db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
441db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
4425c6c1daeSBarry Smith @*/
443d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterScalar(PetscBag bag, void *addr, PetscScalar mdefault, const char *name, const char *help)
444d71ae5a4SJacob Faibussowitsch {
4455c6c1daeSBarry Smith   PetscBagItem item;
4465c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
4475c6c1daeSBarry Smith   PetscBool    printhelp;
4485c6c1daeSBarry Smith 
4495c6c1daeSBarry Smith   PetscFunctionBegin;
4505f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4515f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4525f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
4535f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
4545c6c1daeSBarry Smith   nname[0] = '-';
4555c6c1daeSBarry Smith   nname[1] = 0;
4569566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
4579566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
45848a46eb9SPierre 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));
4599566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetScalar(NULL, bag->bagprefix, nname, &mdefault, NULL));
4605c6c1daeSBarry Smith 
4619566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
4625c6c1daeSBarry Smith   item->dtype  = PETSC_SCALAR;
4635c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
4645f80ce2aSJacob 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);
46502c9f0b5SLisandro Dalcin   item->next           = NULL;
4665c6c1daeSBarry Smith   item->msize          = 1;
4675c6c1daeSBarry Smith   *(PetscScalar *)addr = mdefault;
4689566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
4693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4705c6c1daeSBarry Smith }
4715c6c1daeSBarry Smith 
4725c6c1daeSBarry Smith /*@C
473811af0c4SBarry Smith    PetscBagRegisterBool - add a `PetscBool` to a `PetscBag`
4745c6c1daeSBarry Smith 
475c3339decSBarry Smith    Logically Collective
4765c6c1daeSBarry Smith 
477d8d19677SJose E. Roman    Input Parameters:
4785c6c1daeSBarry Smith +  bag - the bag of values
47909cbc92aSBarry Smith .  addr - location of `PetscBool` in struct, for example `&params->b`
480811af0c4SBarry Smith .  mdefault - the initial value, either `PETSC_FALSE` or `PETSC_TRUE`
4815c6c1daeSBarry Smith .  name - name of the variable
4825c6c1daeSBarry Smith -  help - longer string with more information about the value
4835c6c1daeSBarry Smith 
4845c6c1daeSBarry Smith    Level: beginner
4855c6c1daeSBarry Smith 
486db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
487db781477SPatrick Sanan           `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
488db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
4895c6c1daeSBarry Smith @*/
490d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagRegisterBool(PetscBag bag, void *addr, PetscBool mdefault, const char *name, const char *help)
491d71ae5a4SJacob Faibussowitsch {
4925c6c1daeSBarry Smith   PetscBagItem item;
4935c6c1daeSBarry Smith   char         nname[PETSC_BAG_NAME_LENGTH + 1];
4945c6c1daeSBarry Smith   PetscBool    printhelp;
4955c6c1daeSBarry Smith 
4965c6c1daeSBarry Smith   PetscFunctionBegin;
4975f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
4985f80ce2aSJacob Faibussowitsch   PetscValidPointer(addr, 2);
4995f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 4);
5005f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 5);
5015c6c1daeSBarry 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 */
5025f80ce2aSJacob 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);
5035c6c1daeSBarry Smith   nname[0] = '-';
5045c6c1daeSBarry Smith   nname[1] = 0;
5059566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(nname, name, PETSC_BAG_NAME_LENGTH));
5069566063dSJacob Faibussowitsch   PetscCall(PetscOptionsHasHelp(NULL, &printhelp));
50748a46eb9SPierre Jolivet   if (printhelp) PetscCall((*PetscHelpPrintf)(bag->bagcomm, "  -%s%s <%s>: %s \n", bag->bagprefix ? bag->bagprefix : "", name, PetscBools[mdefault], help));
5089566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetBool(NULL, bag->bagprefix, nname, &mdefault, NULL));
5095c6c1daeSBarry Smith 
5109566063dSJacob Faibussowitsch   PetscCall(PetscNew(&item));
5115c6c1daeSBarry Smith   item->dtype  = PETSC_BOOL;
5125c6c1daeSBarry Smith   item->offset = ((char *)addr) - ((char *)bag);
5135f80ce2aSJacob 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);
51402c9f0b5SLisandro Dalcin   item->next         = NULL;
5155c6c1daeSBarry Smith   item->msize        = 1;
5165c6c1daeSBarry Smith   *(PetscBool *)addr = mdefault;
5179566063dSJacob Faibussowitsch   PetscCall(PetscBagRegister_Private(bag, item, name, help));
5183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5195c6c1daeSBarry Smith }
5205c6c1daeSBarry Smith 
5215c6c1daeSBarry Smith /*@C
522811af0c4SBarry Smith    PetscBagDestroy - Destroys a `PetscBag`
5235c6c1daeSBarry Smith 
524c3339decSBarry Smith    Collective
5255c6c1daeSBarry Smith 
5265c6c1daeSBarry Smith    Input Parameter:
5275c6c1daeSBarry Smith .  bag - the bag of values
5285c6c1daeSBarry Smith 
5295c6c1daeSBarry Smith    Level: beginner
5305c6c1daeSBarry Smith 
531db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
532db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
533db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
5345c6c1daeSBarry Smith @*/
535d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagDestroy(PetscBag *bag)
536d71ae5a4SJacob Faibussowitsch {
5375f80ce2aSJacob Faibussowitsch   PetscBagItem nitem;
5385c6c1daeSBarry Smith 
5395c6c1daeSBarry Smith   PetscFunctionBegin;
5403ba16761SJacob Faibussowitsch   if (!*bag) PetscFunctionReturn(PETSC_SUCCESS);
5415f80ce2aSJacob Faibussowitsch   PetscValidPointer(*bag, 1);
5425f80ce2aSJacob Faibussowitsch   nitem = (*bag)->bagitems;
5435c6c1daeSBarry Smith   while (nitem) {
5445f80ce2aSJacob Faibussowitsch     PetscBagItem item = nitem->next;
5455f80ce2aSJacob Faibussowitsch 
5469566063dSJacob Faibussowitsch     if (nitem->list) PetscCall(PetscStrArrayDestroy(&nitem->list));
5479566063dSJacob Faibussowitsch     PetscCall(PetscFree(nitem));
5485c6c1daeSBarry Smith     nitem = item;
5495c6c1daeSBarry Smith   }
5509566063dSJacob Faibussowitsch   if ((*bag)->bagprefix) PetscCall(PetscFree((*bag)->bagprefix));
5519566063dSJacob Faibussowitsch   PetscCall(PetscFree(*bag));
5523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5535c6c1daeSBarry Smith }
5545c6c1daeSBarry Smith 
5555c6c1daeSBarry Smith /*@
556811af0c4SBarry Smith    PetscBagSetFromOptions - Allows setting entries to a `PetscBag` using the options database
5575c6c1daeSBarry Smith 
558c3339decSBarry Smith    Collective
5595c6c1daeSBarry Smith 
5605c6c1daeSBarry Smith    Input Parameter:
5615c6c1daeSBarry Smith .  bag - the bag of values
5625c6c1daeSBarry Smith 
5635c6c1daeSBarry Smith    Level: beginner
5645c6c1daeSBarry Smith 
565811af0c4SBarry Smith    Note:
566811af0c4SBarry Smith    The options database keys for the entries are of the form `-[bagprefix]_name value`
567811af0c4SBarry Smith 
568db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
569db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
570db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagRegisterEnum()`
5715c6c1daeSBarry Smith @*/
572d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetFromOptions(PetscBag bag)
573d71ae5a4SJacob Faibussowitsch {
5745c6c1daeSBarry Smith   PetscBagItem nitem = bag->bagitems;
5755c6c1daeSBarry Smith   char         name[PETSC_BAG_NAME_LENGTH + 1], helpname[PETSC_BAG_NAME_LENGTH + PETSC_BAG_HELP_LENGTH + 3];
5765c6c1daeSBarry Smith   PetscInt     n;
5775c6c1daeSBarry Smith 
5785c6c1daeSBarry Smith   PetscFunctionBegin;
5795f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
5809566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(helpname, bag->bagname, sizeof(helpname)));
5819566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(helpname, " ", sizeof(helpname)));
5829566063dSJacob Faibussowitsch   PetscCall(PetscStrlcat(helpname, bag->baghelp, sizeof(helpname)));
583d0609cedSBarry Smith   PetscOptionsBegin(bag->bagcomm, bag->bagprefix, helpname, NULL);
5845c6c1daeSBarry Smith   while (nitem) {
5855c6c1daeSBarry Smith     name[0] = '-';
5865c6c1daeSBarry Smith     name[1] = 0;
5879566063dSJacob Faibussowitsch     PetscCall(PetscStrlcat(name, nitem->name, sizeof(name)));
5885c6c1daeSBarry Smith     if (nitem->dtype == PETSC_CHAR) { /* special handling for fortran required? [due to space padding vs null termination] */
5895c6c1daeSBarry Smith       char *value = (char *)(((char *)bag) + nitem->offset);
5909566063dSJacob Faibussowitsch       PetscCall(PetscOptionsString(name, nitem->help, "", value, value, nitem->msize, NULL));
5915c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_REAL) {
5925c6c1daeSBarry Smith       PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
5935c6c1daeSBarry Smith       if (nitem->msize == 1) {
5949566063dSJacob Faibussowitsch         PetscCall(PetscOptionsReal(name, nitem->help, "", *value, value, NULL));
5955c6c1daeSBarry Smith       } else {
5965c6c1daeSBarry Smith         n = nitem->msize;
5979566063dSJacob Faibussowitsch         PetscCall(PetscOptionsRealArray(name, nitem->help, "", value, &n, NULL));
5985c6c1daeSBarry Smith       }
5995c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_SCALAR) {
6005c6c1daeSBarry Smith       PetscScalar *value = (PetscScalar *)(((char *)bag) + nitem->offset);
6019566063dSJacob Faibussowitsch       PetscCall(PetscOptionsScalar(name, nitem->help, "", *value, value, NULL));
6025c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_INT) {
6035c6c1daeSBarry Smith       PetscInt *value = (PetscInt *)(((char *)bag) + nitem->offset);
6045c6c1daeSBarry Smith       if (nitem->msize == 1) {
6059566063dSJacob Faibussowitsch         PetscCall(PetscOptionsInt(name, nitem->help, "", *value, value, NULL));
6065c6c1daeSBarry Smith       } else {
6075c6c1daeSBarry Smith         n = nitem->msize;
6089566063dSJacob Faibussowitsch         PetscCall(PetscOptionsIntArray(name, nitem->help, "", value, &n, NULL));
6095c6c1daeSBarry Smith       }
6105c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_ENUM) {
6115c6c1daeSBarry Smith       PetscEnum *value = (PetscEnum *)(((char *)bag) + nitem->offset);
6125c6c1daeSBarry Smith       PetscInt   i     = 0;
6139371c9d4SSatish Balay       while (nitem->list[i++])
6149371c9d4SSatish Balay         ;
6159566063dSJacob Faibussowitsch       PetscCall(PetscOptionsEnum(name, nitem->help, nitem->list[i - 3], (const char *const *)nitem->list, *value, value, NULL));
6165c6c1daeSBarry Smith     } else if (nitem->dtype == PETSC_BOOL) {
6175c6c1daeSBarry Smith       PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
618dd66f111SBlaise Bourdin       if (nitem->msize == 1) {
6199566063dSJacob Faibussowitsch         PetscCall(PetscOptionsBool(name, nitem->help, "", *value, value, NULL));
620dd66f111SBlaise Bourdin       } else {
621dd66f111SBlaise Bourdin         n = nitem->msize;
6229566063dSJacob Faibussowitsch         PetscCall(PetscOptionsBoolArray(name, nitem->help, "", value, &n, NULL));
623dd66f111SBlaise Bourdin       }
6245c6c1daeSBarry Smith     }
6255c6c1daeSBarry Smith     nitem = nitem->next;
6265c6c1daeSBarry Smith   }
627d0609cedSBarry Smith   PetscOptionsEnd();
6283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6295c6c1daeSBarry Smith }
6305c6c1daeSBarry Smith 
6315c6c1daeSBarry Smith /*@C
6325c6c1daeSBarry Smith    PetscBagView - Views a bag of values as either ASCII text or a binary file
6335c6c1daeSBarry Smith 
634c3339decSBarry Smith    Collective
6355c6c1daeSBarry Smith 
636d8d19677SJose E. Roman    Input Parameters:
6375c6c1daeSBarry Smith +  bag - the bag of values
6385c6c1daeSBarry Smith -  viewer - location to view the values
6395c6c1daeSBarry Smith 
6405c6c1daeSBarry Smith    Level: beginner
6415c6c1daeSBarry Smith 
642811af0c4SBarry Smith    Note:
643811af0c4SBarry Smith    Currently PETSc bags saved in a binary file can only be read back
64409cbc92aSBarry Smith    in on a machine with the same binary format.
6455c6c1daeSBarry Smith 
646db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagLoad()`, `PetscBagGetData()`
647db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`, `PetscBagRegisterEnum()`
648db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`
6495c6c1daeSBarry Smith @*/
650d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagView(PetscBag bag, PetscViewer view)
651d71ae5a4SJacob Faibussowitsch {
6525c6c1daeSBarry Smith   PetscBool    isascii, isbinary;
6535c6c1daeSBarry Smith   PetscBagItem nitem = bag->bagitems;
6545c6c1daeSBarry Smith 
6555c6c1daeSBarry Smith   PetscFunctionBegin;
6565f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
6575f80ce2aSJacob Faibussowitsch   PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 2);
6589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERASCII, &isascii));
6599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
6605c6c1daeSBarry Smith   if (isascii) {
6613ffde785SBarry Smith     if (bag->bagprefix) {
6629566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object:  %s (%s) %s\n", bag->bagname, bag->bagprefix, bag->baghelp));
6633ffde785SBarry Smith     } else {
6649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(view, "PetscBag Object:  %s %s\n", bag->bagname, bag->baghelp));
6653ffde785SBarry Smith     }
6665c6c1daeSBarry Smith     while (nitem) {
6675c6c1daeSBarry Smith       if (nitem->dtype == PETSC_CHAR) {
6685c6c1daeSBarry Smith         char *value             = (char *)(((char *)bag) + nitem->offset);
669da81f932SPierre Jolivet         char  tmp               = value[nitem->msize - 1]; /* special handling for fortran chars without null terminator */
6705c6c1daeSBarry Smith         value[nitem->msize - 1] = 0;
6719566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %s; %s\n", nitem->name, value, nitem->help));
6725c6c1daeSBarry Smith         value[nitem->msize - 1] = tmp;
6735c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_REAL) {
6745c6c1daeSBarry Smith         PetscReal *value = (PetscReal *)(((char *)bag) + nitem->offset);
6755c6c1daeSBarry Smith         PetscInt   i;
6769566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
67748a46eb9SPierre Jolivet         for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%g ", (double)value[i]));
6789566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
6795c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_SCALAR) {
6805c6c1daeSBarry Smith         PetscScalar value = *(PetscScalar *)(((char *)bag) + nitem->offset);
6815c6c1daeSBarry Smith #if defined(PETSC_USE_COMPLEX)
6828627564fSBarry Smith         if ((double)PetscImaginaryPart(value)) {
6839566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g + %gi; %s\n", nitem->name, (double)PetscRealPart(value), (double)PetscImaginaryPart(value), nitem->help));
6848627564fSBarry Smith         } else {
6859566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)PetscRealPart(value), nitem->help));
6868627564fSBarry Smith         }
6875c6c1daeSBarry Smith #else
6889566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %g; %s\n", nitem->name, (double)value, nitem->help));
6895c6c1daeSBarry Smith #endif
6905c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_INT) {
6915c6c1daeSBarry Smith         PetscInt i, *value = (PetscInt *)(((char *)bag) + nitem->offset);
6929566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
69348a46eb9SPierre Jolivet         for (i = 0; i < nitem->msize; i++) PetscCall(PetscViewerASCIIPrintf(view, "%" PetscInt_FMT " ", value[i]));
6949566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
6955c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_BOOL) {
696dd66f111SBlaise Bourdin         PetscBool *value = (PetscBool *)(((char *)bag) + nitem->offset);
697dd66f111SBlaise Bourdin         PetscInt   i;
6985c6c1daeSBarry Smith         /* some Fortran compilers use -1 as boolean */
6999566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = ", nitem->name));
700dd66f111SBlaise Bourdin         for (i = 0; i < nitem->msize; i++) {
701dd66f111SBlaise Bourdin           if (((int)value[i]) == -1) value[i] = PETSC_TRUE;
7025c6c1daeSBarry 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 */
7035f80ce2aSJacob 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]));
7049566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(view, " %s", PetscBools[value[i]]));
705dd66f111SBlaise Bourdin         }
7069566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "; %s\n", nitem->help));
7075c6c1daeSBarry Smith       } else if (nitem->dtype == PETSC_ENUM) {
7085c6c1daeSBarry Smith         PetscEnum value = *(PetscEnum *)(((char *)bag) + nitem->offset);
7095c6c1daeSBarry Smith         PetscInt  i     = 0;
7109371c9d4SSatish Balay         while (nitem->list[i++])
7119371c9d4SSatish Balay           ;
7129566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(view, "  %s = %s; (%s) %s\n", nitem->name, nitem->list[value], nitem->list[i - 3], nitem->help));
7135c6c1daeSBarry Smith       }
7145c6c1daeSBarry Smith       nitem = nitem->next;
7155c6c1daeSBarry Smith     }
7165c6c1daeSBarry Smith   } else if (isbinary) {
7175c6c1daeSBarry Smith     PetscInt          classid           = PETSC_BAG_FILE_CLASSID, dtype;
7185c6c1daeSBarry Smith     PetscInt          deprecatedbagsize = 0;
719a261c58fSBarry Smith     PetscViewerFormat format;
7209566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &classid, 1, PETSC_INT));
7219566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &deprecatedbagsize, 1, PETSC_INT));
7229566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, &bag->count, 1, PETSC_INT));
7239566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, bag->bagname, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
7249566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWrite(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
7255c6c1daeSBarry Smith     while (nitem) {
7269566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &nitem->offset, 1, PETSC_INT));
7275c6c1daeSBarry Smith       dtype = (PetscInt)nitem->dtype;
7289566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &dtype, 1, PETSC_INT));
7299566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, nitem->name, PETSC_BAG_NAME_LENGTH, PETSC_CHAR));
7309566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, nitem->help, PETSC_BAG_HELP_LENGTH, PETSC_CHAR));
7319566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, &nitem->msize, 1, PETSC_INT));
7325c6c1daeSBarry Smith       /* some Fortran compilers use -1 as boolean */
7335c6c1daeSBarry Smith       if (dtype == PETSC_BOOL && ((*(int *)(((char *)bag) + nitem->offset) == -1))) *(int *)(((char *)bag) + nitem->offset) = PETSC_TRUE;
7345c6c1daeSBarry Smith 
7359566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryWrite(view, (((char *)bag) + nitem->offset), nitem->msize, nitem->dtype));
73648a46eb9SPierre Jolivet       if (dtype == PETSC_ENUM) PetscCall(PetscViewerBinaryWriteStringArray(view, (const char *const *)nitem->list));
7375c6c1daeSBarry Smith       nitem = nitem->next;
7385c6c1daeSBarry Smith     }
7399566063dSJacob Faibussowitsch     PetscCall(PetscViewerGetFormat(view, &format));
740a261c58fSBarry Smith     if (format == PETSC_VIEWER_BINARY_MATLAB) {
741a261c58fSBarry Smith       MPI_Comm comm;
742a261c58fSBarry Smith       FILE    *info;
7439566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
7449566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryGetInfoPointer(view, &info));
7459566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#--- begin code written by PetscViewerBinary for MATLAB format ---#\n"));
7469566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#$$ Set.%s = PetscBinaryRead(fd);\n", bag->bagname));
7479566063dSJacob Faibussowitsch       PetscCall(PetscFPrintf(comm, info, "#--- end code written by PetscViewerBinary for MATLAB format ---#\n\n"));
748a261c58fSBarry Smith     }
749a261c58fSBarry Smith   }
7503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7515c6c1daeSBarry Smith }
7525c6c1daeSBarry Smith 
7535c6c1daeSBarry Smith /*@C
75409cbc92aSBarry Smith   PetscBagViewFromOptions - Processes command line options to determine if/how a `PetscBag` is to be viewed.
755173f9484SMatthew G. Knepley 
756c3339decSBarry Smith   Collective
757173f9484SMatthew G. Knepley 
758173f9484SMatthew G. Knepley   Input Parameters:
759173f9484SMatthew G. Knepley + obj   - the object
76009cbc92aSBarry Smith . bobj  - optional other object that provides prefix (if `NULL` then the prefix in obj is used)
761173f9484SMatthew G. Knepley - optionname - option to activate viewing
762478db826SMatthew G. Knepley 
763173f9484SMatthew G. Knepley   Level: intermediate
764478db826SMatthew G. Knepley 
765db781477SPatrick Sanan .seealso: `PetscBagCreate()`, `PetscBag`, `PetscViewer`
766173f9484SMatthew G. Knepley @*/
767d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagViewFromOptions(PetscBag bag, PetscObject bobj, const char optionname[])
768d71ae5a4SJacob Faibussowitsch {
769173f9484SMatthew G. Knepley   static PetscBool  incall = PETSC_FALSE;
770173f9484SMatthew G. Knepley   PetscViewer       viewer;
771173f9484SMatthew G. Knepley   PetscViewerFormat format;
772173f9484SMatthew G. Knepley   const char       *prefix, *bprefix = NULL;
773173f9484SMatthew G. Knepley   PetscBool         flg;
774173f9484SMatthew G. Knepley 
775173f9484SMatthew G. Knepley   PetscFunctionBegin;
7763ba16761SJacob Faibussowitsch   if (incall) PetscFunctionReturn(PETSC_SUCCESS);
777173f9484SMatthew G. Knepley   incall = PETSC_TRUE;
7785f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
7799566063dSJacob Faibussowitsch   if (bobj) PetscCall(PetscObjectGetOptionsPrefix(bobj, &bprefix));
780173f9484SMatthew G. Knepley   prefix = bobj ? bprefix : bag->bagprefix;
7819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(bag->bagcomm, NULL, prefix, optionname, &viewer, &format, &flg));
782173f9484SMatthew G. Knepley   if (flg) {
7839566063dSJacob Faibussowitsch     PetscCall(PetscViewerPushFormat(viewer, format));
7849566063dSJacob Faibussowitsch     PetscCall(PetscBagView(bag, viewer));
7859566063dSJacob Faibussowitsch     PetscCall(PetscViewerFlush(viewer));
7869566063dSJacob Faibussowitsch     PetscCall(PetscViewerPopFormat(viewer));
7879566063dSJacob Faibussowitsch     PetscCall(PetscViewerDestroy(&viewer));
788173f9484SMatthew G. Knepley   }
789173f9484SMatthew G. Knepley   incall = PETSC_FALSE;
7903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
791173f9484SMatthew G. Knepley }
792173f9484SMatthew G. Knepley 
793173f9484SMatthew G. Knepley /*@C
7945c6c1daeSBarry Smith    PetscBagLoad - Loads a bag of values from a binary file
7955c6c1daeSBarry Smith 
796c3339decSBarry Smith    Collective
7975c6c1daeSBarry Smith 
798d8d19677SJose E. Roman    Input Parameters:
7995c6c1daeSBarry Smith +  viewer - file to load values from
8005c6c1daeSBarry Smith -  bag - the bag of values
8015c6c1daeSBarry Smith 
8025c6c1daeSBarry Smith    Level: beginner
8035c6c1daeSBarry Smith 
80409cbc92aSBarry Smith    Note:
80509cbc92aSBarry Smith     You must have created and registered all the fields in the bag before loading into it. This only loads values.
80609cbc92aSBarry Smith 
807db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagDestroy()`, `PetscBagView()`, `PetscBagGetData()`
808db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
809db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagGetName()`, `PetscBagRegisterEnum()`
8105c6c1daeSBarry Smith @*/
811d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagLoad(PetscViewer view, PetscBag bag)
812d71ae5a4SJacob Faibussowitsch {
8135c6c1daeSBarry Smith   PetscBool    isbinary;
8145f80ce2aSJacob Faibussowitsch   PetscInt     classid, bagcount, dtype, msize, offset, deprecatedbagsize;
8155c6c1daeSBarry Smith   char         name[PETSC_BAG_NAME_LENGTH], help[PETSC_BAG_HELP_LENGTH], **list;
8165c6c1daeSBarry Smith   PetscBagItem nitem;
8175c6c1daeSBarry Smith   MPI_Comm     comm;
8185c6c1daeSBarry Smith   PetscMPIInt  flag;
8195c6c1daeSBarry Smith 
8205c6c1daeSBarry Smith   PetscFunctionBegin;
8215f80ce2aSJacob Faibussowitsch   PetscValidHeaderSpecific(view, PETSC_VIEWER_CLASSID, 1);
8225f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 2);
8239566063dSJacob Faibussowitsch   PetscCall(PetscObjectGetComm((PetscObject)view, &comm));
8249566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_compare(comm, bag->bagcomm, &flag));
8255f80ce2aSJacob Faibussowitsch   PetscCheck(flag == MPI_CONGRUENT || flag == MPI_IDENT, PETSC_COMM_SELF, PETSC_ERR_ARG_NOTSAMECOMM, "Different communicators in the viewer and bag");
8269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)view, PETSCVIEWERBINARY, &isbinary));
8275f80ce2aSJacob Faibussowitsch   PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_SUP, "No support for this viewer type");
8285c6c1daeSBarry Smith 
8299566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &classid, 1, NULL, PETSC_INT));
8305f80ce2aSJacob Faibussowitsch   PetscCheck(classid == PETSC_BAG_FILE_CLASSID, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not PetscBag next in binary file");
8319566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &deprecatedbagsize, 1, NULL, PETSC_INT));
8329566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, &bagcount, 1, NULL, PETSC_INT));
8335f80ce2aSJacob 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);
8349566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, bag->bagname, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
8359566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryRead(view, bag->baghelp, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
8365c6c1daeSBarry Smith 
8375c6c1daeSBarry Smith   nitem = bag->bagitems;
8385f80ce2aSJacob Faibussowitsch   for (PetscInt i = 0; i < bagcount; i++) {
8399566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &offset, 1, NULL, PETSC_INT));
8405c6c1daeSBarry Smith     /* ignore the offset in the file */
8419566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &dtype, 1, NULL, PETSC_INT));
8429566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, name, PETSC_BAG_NAME_LENGTH, NULL, PETSC_CHAR));
8439566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, help, PETSC_BAG_HELP_LENGTH, NULL, PETSC_CHAR));
8449566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(view, &msize, 1, NULL, PETSC_INT));
8455c6c1daeSBarry Smith 
8465c6c1daeSBarry Smith     if (dtype == (PetscInt)PETSC_CHAR) {
8479566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_CHAR));
8485c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_REAL) {
8499566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_REAL));
8505c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_SCALAR) {
8519566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_SCALAR));
8525c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_INT) {
8539566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_INT));
8545c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_BOOL) {
8559566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, msize, NULL, PETSC_BOOL));
8565c6c1daeSBarry Smith     } else if (dtype == (PetscInt)PETSC_ENUM) {
8579566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryRead(view, ((char *)bag) + nitem->offset, 1, NULL, PETSC_ENUM));
8589566063dSJacob Faibussowitsch       PetscCall(PetscViewerBinaryReadStringArray(view, &list));
8595c6c1daeSBarry Smith       /* don't need to save list because it is already registered in the bag */
8609566063dSJacob Faibussowitsch       PetscCall(PetscFree(list));
8615c6c1daeSBarry Smith     }
8625c6c1daeSBarry Smith     nitem = nitem->next;
8635c6c1daeSBarry Smith   }
8643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8655c6c1daeSBarry Smith }
8665c6c1daeSBarry Smith 
867e8976759SBarry Smith /*@C
86809cbc92aSBarry 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,
86909cbc92aSBarry Smith     can have values set from the options database
8705c6c1daeSBarry Smith 
871d083f849SBarry Smith   Collective
8725c6c1daeSBarry Smith 
8735c6c1daeSBarry Smith   Input Parameters:
8745c6c1daeSBarry Smith +  comm - communicator to share bag
875811af0c4SBarry Smith -  bagsize - size of the C structure holding the values, for example sizeof(mystruct)
8765c6c1daeSBarry Smith 
8775c6c1daeSBarry Smith   Output Parameter:
8785c6c1daeSBarry Smith .   bag - the bag of values
8795c6c1daeSBarry Smith 
88009cbc92aSBarry Smith   Level: Intermediate
88109cbc92aSBarry Smith 
8825c6c1daeSBarry Smith    Notes:
883811af0c4SBarry Smith    After creating the bag, for each entry in the C struct call the appropriate `PetscBagRegisterInt()` etc to define the C structs layout
884811af0c4SBarry Smith 
885811af0c4SBarry Smith    The size of the A struct must be small enough to fit in a `PetscInt`; by default
886811af0c4SBarry Smith    `PetscInt` is 4 bytes; this means a bag cannot be larger than 2 gigabytes in length.
8875c6c1daeSBarry Smith    The warning about casting to a shorter length can be ignored below unless your A struct is too large
8885c6c1daeSBarry Smith 
889db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
890db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
891db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
8925c6c1daeSBarry Smith @*/
893d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagCreate(MPI_Comm comm, size_t bagsize, PetscBag *bag)
894d71ae5a4SJacob Faibussowitsch {
8955f80ce2aSJacob Faibussowitsch   const size_t totalsize = bagsize + sizeof(struct _n_PetscBag) + sizeof(PetscScalar);
8965c6c1daeSBarry Smith 
8975c6c1daeSBarry Smith   PetscFunctionBegin;
8985f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 3);
8999566063dSJacob Faibussowitsch   PetscCall(PetscInfo(NULL, "Creating Bag with total size %d\n", (int)totalsize));
9009566063dSJacob Faibussowitsch   PetscCall(PetscCalloc(totalsize, bag));
901a297a907SKarl Rupp 
9025f80ce2aSJacob Faibussowitsch   (*bag)->bagsize        = totalsize;
9035c6c1daeSBarry Smith   (*bag)->bagcomm        = comm;
9040298fd71SBarry Smith   (*bag)->bagprefix      = NULL;
9055c6c1daeSBarry Smith   (*bag)->structlocation = (void *)(((char *)(*bag)) + sizeof(PetscScalar) * (sizeof(struct _n_PetscBag) / sizeof(PetscScalar)) + sizeof(PetscScalar));
9063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9075c6c1daeSBarry Smith }
9085c6c1daeSBarry Smith 
9095c6c1daeSBarry Smith /*@C
9105c6c1daeSBarry Smith     PetscBagSetName - Sets the name of a bag of values
9115c6c1daeSBarry Smith 
9125c6c1daeSBarry Smith   Not Collective
9135c6c1daeSBarry Smith 
9145c6c1daeSBarry Smith   Level: Intermediate
9155c6c1daeSBarry Smith 
9165c6c1daeSBarry Smith   Input Parameters:
9175c6c1daeSBarry Smith +   bag - the bag of values
9185c6c1daeSBarry Smith .   name - the name assigned to the bag
9195c6c1daeSBarry Smith -   help - help message for bag
9205c6c1daeSBarry Smith 
921db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagGetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
922db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
923db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9245c6c1daeSBarry Smith @*/
925d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetName(PetscBag bag, const char *name, const char *help)
926d71ae5a4SJacob Faibussowitsch {
9275c6c1daeSBarry Smith   PetscFunctionBegin;
9285f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9295f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(name, 2);
9305f80ce2aSJacob Faibussowitsch   PetscValidCharPointer(help, 3);
9319566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(bag->bagname, name, PETSC_BAG_NAME_LENGTH - 1));
9329566063dSJacob Faibussowitsch   PetscCall(PetscStrncpy(bag->baghelp, help, PETSC_BAG_HELP_LENGTH - 1));
9333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9345c6c1daeSBarry Smith }
9355c6c1daeSBarry Smith 
9365c6c1daeSBarry Smith /*@C
9375c6c1daeSBarry Smith     PetscBagGetName - Gets the name of a bag of values
9385c6c1daeSBarry Smith 
9395c6c1daeSBarry Smith   Not Collective
9405c6c1daeSBarry Smith 
9415c6c1daeSBarry Smith   Level: Intermediate
9425c6c1daeSBarry Smith 
9435c6c1daeSBarry Smith   Input Parameter:
9445c6c1daeSBarry Smith .   bag - the bag of values
9455c6c1daeSBarry Smith 
9465c6c1daeSBarry Smith   Output Parameter:
9475c6c1daeSBarry Smith .   name - the name assigned to the bag
9485c6c1daeSBarry Smith 
949db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`, `PetscBagGetData()`
950db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
951db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9525c6c1daeSBarry Smith @*/
953d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagGetName(PetscBag bag, char **name)
954d71ae5a4SJacob Faibussowitsch {
9555c6c1daeSBarry Smith   PetscFunctionBegin;
9565f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9575f80ce2aSJacob Faibussowitsch   PetscValidPointer(name, 2);
9585c6c1daeSBarry Smith   *name = bag->bagname;
9593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9605c6c1daeSBarry Smith }
9615c6c1daeSBarry Smith 
9625c6c1daeSBarry Smith /*@C
9635c6c1daeSBarry Smith     PetscBagGetData - Gives back the user - access to memory that
964811af0c4SBarry Smith     can be used for storing user-data-structure
9655c6c1daeSBarry Smith 
9665c6c1daeSBarry Smith   Not Collective
9675c6c1daeSBarry Smith 
9685c6c1daeSBarry Smith   Input Parameter:
9695c6c1daeSBarry Smith .   bag - the bag of values
9705c6c1daeSBarry Smith 
9715c6c1daeSBarry Smith   Output Parameter:
97209cbc92aSBarry 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
97309cbc92aSBarry Smith     defining the bag
97409cbc92aSBarry Smith 
97509cbc92aSBarry Smith   Level: Intermediate
9765c6c1daeSBarry Smith 
977db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagSetName()`, `PetscBagView()`, `PetscBagLoad()`
978db781477SPatrick Sanan           `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
979db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
9805c6c1daeSBarry Smith @*/
981d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagGetData(PetscBag bag, void **data)
982d71ae5a4SJacob Faibussowitsch {
9835c6c1daeSBarry Smith   PetscFunctionBegin;
9845f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
9855f80ce2aSJacob Faibussowitsch   PetscValidPointer(data, 2);
9865c6c1daeSBarry Smith   *data = bag->structlocation;
9873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9885c6c1daeSBarry Smith }
9895c6c1daeSBarry Smith 
9905c6c1daeSBarry Smith /*@C
9915c6c1daeSBarry Smith   PetscBagSetOptionsPrefix - Sets the prefix used for searching for all
992811af0c4SBarry Smith   `PetscBag` items in the options database.
9935c6c1daeSBarry Smith 
99409cbc92aSBarry Smith   Logically Collective
9955c6c1daeSBarry Smith 
9965c6c1daeSBarry Smith   Level: Intermediate
9975c6c1daeSBarry Smith 
9985c6c1daeSBarry Smith   Input Parameters:
9995c6c1daeSBarry Smith +   bag - the bag of values
10005c6c1daeSBarry Smith -   prefix - the prefix to prepend all Bag item names with.
10015c6c1daeSBarry Smith 
100209cbc92aSBarry Smith   Note:
100309cbc92aSBarry Smith   Must be called prior to registering any of the bag items.
10045c6c1daeSBarry Smith 
1005db781477SPatrick Sanan .seealso: `PetscBag`, `PetscBagRegisterReal()`, `PetscBagRegisterInt()`, `PetscBagRegisterBool()`, `PetscBagRegisterScalar()`
1006db781477SPatrick Sanan           `PetscBagSetFromOptions()`, `PetscBagCreate()`, `PetscBagDestroy()`, `PetscBagRegisterEnum()`
10075c6c1daeSBarry Smith @*/
10085c6c1daeSBarry Smith 
1009d71ae5a4SJacob Faibussowitsch PetscErrorCode PetscBagSetOptionsPrefix(PetscBag bag, const char pre[])
1010d71ae5a4SJacob Faibussowitsch {
10115c6c1daeSBarry Smith   PetscFunctionBegin;
10125f80ce2aSJacob Faibussowitsch   PetscValidPointer(bag, 1);
10135f80ce2aSJacob Faibussowitsch   if (pre) {
10145f80ce2aSJacob Faibussowitsch     PetscValidCharPointer(pre, 2);
10155f80ce2aSJacob Faibussowitsch     PetscCheck(pre[0] != '-', PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Options prefix should not begin with a hyphen");
10169566063dSJacob Faibussowitsch     PetscCall(PetscFree(bag->bagprefix));
10179566063dSJacob Faibussowitsch     PetscCall(PetscStrallocpy(pre, &(bag->bagprefix)));
10189566063dSJacob Faibussowitsch   } else PetscCall(PetscFree(bag->bagprefix));
10193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
10205c6c1daeSBarry Smith }
1021ffb7e86cSMatthew G. Knepley 
1022ffb7e86cSMatthew G. Knepley /*@C
1023ffb7e86cSMatthew G. Knepley   PetscBagGetNames - Get the names of all entries in the bag
1024ffb7e86cSMatthew G. Knepley 
102509cbc92aSBarry Smith   Not Collective
1026ffb7e86cSMatthew G. Knepley 
1027*2fe279fdSBarry Smith   Input Parameter:
1028*2fe279fdSBarry Smith . bag   - the bag of values
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