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