xref: /petsc/src/sys/tutorials/ex5.c (revision 1b37a2a7cc4a4fb30c3e967db1c694c0a1013f51)
1 static char help[] = "Demonstrates using the PetscBag Object\n\n";
2 
3 #include <petscsys.h>
4 #include <petscbag.h>
5 #include <petscviewer.h>
6 
7 /*
8   Enum variables can be stored in a bag but require a string array
9   to name their fields.  The fourth entry in this example is the name
10   of the enum, the fifth is the prefix (none in this case), and the last
11   entry is the null string.
12 */
13 typedef enum {
14   THIS      = 0,
15   THAT      = 1,
16   THE_OTHER = 2
17 } YourChoice;
18 const char *EnumeratedChoices[] = {"THIS", "THAT", "THE_OTHER", "EnumeratedChoices", "", 0};
19 
20 /*
21   Data structures can be used in a bag as long as they
22   are declared in the bag with a variable, not with a pointer.
23 */
24 typedef struct {
25   PetscReal x1, x2;
26 } TwoVec;
27 
28 /*
29   Define a C struct that will contain my program's parameters.
30 
31   A PETSc bag is merely a representation of a C struct that can be printed, saved to a file and loaded from a file.
32 */
33 typedef struct {
34   PetscScalar   W;
35   PetscReal     rho;
36   TwoVec        pos;
37   PetscInt      Ii;
38   PetscInt      iarray[3];
39   PetscReal     rarray[2];
40   PetscBool     T;
41   PetscBool     Tarray[3];
42   PetscDataType dt;
43   char          filename[PETSC_MAX_PATH_LEN];
44   YourChoice    which;
45 } Parameter;
46 
47 int main(int argc, char **argv)
48 {
49   PetscBag    bag;
50   Parameter  *params;
51   PetscViewer viewer;
52   PetscBool   flg;
53   char        filename[PETSC_MAX_PATH_LEN] = "binaryoutput";
54 
55   /*
56     Every PETSc routine should begin with the PetscInitialize() routine.
57     argc, argv - These command line arguments are taken to extract the options
58                  supplied to PETSc and options supplied to MPI.
59     help       - When PETSc executable is invoked with the option -help,
60                  it prints the various options that can be applied at
61                  runtime.  The user can use the "help" variable place
62                  additional help messages in this printout.
63   */
64   PetscFunctionBeginUser;
65   PetscCall(PetscInitialize(&argc, &argv, (char *)0, help));
66 
67   /* Create an empty bag */
68   PetscCall(PetscBagCreate(PETSC_COMM_WORLD, sizeof(Parameter), &bag));
69   PetscCall(PetscBagGetData(bag, (void **)&params));
70 
71   /* register variables, defaults, names, help strings */
72   PetscCall(PetscBagSetName(bag, "ParameterBag", "contains parameters for simulations of top-secret, dangerous physics"));
73   PetscCall(PetscBagSetOptionsPrefix(bag, "pbag_"));
74   PetscCall(PetscBagRegisterString(bag, &params->filename, PETSC_MAX_PATH_LEN, "myfile", "filename", "Name of secret file"));
75   PetscCall(PetscBagRegisterReal(bag, &params->rho, 3.0, "rho", "Density, kg/m^3"));
76   PetscCall(PetscBagRegisterScalar(bag, &params->W, 5.0, "W", "Vertical velocity, m/sec"));
77   PetscCall(PetscBagRegisterInt(bag, &params->Ii, 2, "modes_x", "Number of modes in x-direction"));
78 
79   params->iarray[0] = 1;
80   params->iarray[1] = 2;
81   params->iarray[2] = 3;
82 
83   PetscCall(PetscBagRegisterIntArray(bag, &params->iarray, 3, "int_array", "Int array with 3 locations"));
84 
85   params->rarray[0] = -1.0;
86   params->rarray[1] = -2.0;
87 
88   PetscCall(PetscBagRegisterRealArray(bag, &params->rarray, 2, "real_array", "Real array with 2 locations"));
89   PetscCall(PetscBagRegisterBool(bag, &params->T, PETSC_FALSE, "do_output", "Write output file (yes/no)"));
90   PetscCall(PetscBagRegisterBoolArray(bag, &params->Tarray, 3, "bool_array", "Bool array with 3 locations"));
91   PetscCall(PetscBagRegisterEnum(bag, &params->dt, PetscDataTypes, (PetscEnum)PETSC_INT, "dt", "meaningless datatype"));
92   PetscCall(PetscBagRegisterReal(bag, &params->pos.x1, 1.0, "x1", "x position"));
93   PetscCall(PetscBagRegisterReal(bag, &params->pos.x2, 1.9, "x2", "y position"));
94   PetscCall(PetscBagRegisterEnum(bag, &params->which, EnumeratedChoices, (PetscEnum)THAT, "choose", "Express yourself by choosing among enumerated things"));
95 
96   /* This option allows loading user-provided PetscBag */
97   PetscCall(PetscOptionsGetString(NULL, NULL, "-f", filename, sizeof(filename), &flg));
98   if (!flg) {
99     /* write bag to stdio & binary file */
100     PetscCall(PetscBagView(bag, PETSC_VIEWER_STDOUT_WORLD));
101     PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, filename, FILE_MODE_WRITE, &viewer));
102     PetscCall(PetscBagView(bag, viewer));
103     PetscCall(PetscViewerDestroy(&viewer));
104   }
105 
106   PetscCall(PetscMemzero(params, sizeof(Parameter)));
107 
108   /* load bag from file & write to stdio */
109   PetscCall(PetscViewerBinaryOpen(PETSC_COMM_WORLD, filename, FILE_MODE_READ, &viewer));
110   PetscCall(PetscBagLoad(viewer, bag));
111   PetscCall(PetscViewerDestroy(&viewer));
112   PetscCall(PetscBagSetFromOptions(bag));
113   PetscCall(PetscBagView(bag, PETSC_VIEWER_STDOUT_WORLD));
114 
115   /* reuse the parameter struct */
116   PetscCall(PetscBagGetData(bag, (void **)&params));
117   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "The value of rho after loading is: %f\n", (double)params->rho));
118 
119   /* clean up and exit */
120   PetscCall(PetscBagDestroy(&bag));
121   PetscCall(PetscFinalize());
122   return 0;
123 }
124 
125 /*TEST
126 
127    test:
128       args: -pbag_rho 44 -pbag_do_output true
129       requires: !complex
130 
131    test:
132       suffix: yaml
133       requires: !complex
134       args: -options_file bag.yml -options_view
135       filter: grep -E -v "(options_view)"
136       localrunfiles: bag.yml
137 
138 TEST*/
139