1 #include <silo.h>
2 
3 #include <map>
4 #include <string>
5 #include <iostream>
6 
7 #include <assert.h>
8 #include <string.h>
9 
10 using std::map;
11 using std::string;
12 using std::cout;
13 using std::endl;
14 using std::cerr;
15 
16 typedef map<string, string> strmap_t;
17 
18 #define ARG_OPT(A) (!strncmp(argv[i],#A,sizeof(#A)))
19 
get_coord(DBucdmesh const * ucdm,int nid,double * x,double * y,double * z)20 static void get_coord(DBucdmesh const *ucdm, int nid, double* x, double* y, double* z)
21 {
22     if (ucdm->datatype == DB_DOUBLE)
23     {
24         *x = ((double*)(ucdm->coords[0]))[nid];
25         *y = ((double*)(ucdm->coords[1]))[nid];
26         *z = ((double*)(ucdm->coords[2]))[nid];
27     }
28     else if (ucdm->datatype == DB_FLOAT)
29     {
30         *x = ((float*)(ucdm->coords[0]))[nid];
31         *y = ((float*)(ucdm->coords[1]))[nid];
32         *z = ((float*)(ucdm->coords[2]))[nid];
33     }
34     else
35     {
36         assert(0);
37     }
38 }
39 
get_zoneid(DBzonelist const * zl,int zidx)40 static unsigned long long get_zoneid(DBzonelist const *zl, int zidx)
41 {
42     if (!zl->gzoneno) return (unsigned long long)-1;
43 
44     switch (zl->gnznodtype)
45     {
46         case DB_INT: {int *p = (int *) zl->gzoneno; return (unsigned long long) p[zidx]; }
47         case DB_LONG: { long *p = (long *) zl->gzoneno; return (unsigned long long) p[zidx]; }
48         case DB_LONG_LONG: { long long *p = (long long *) zl->gzoneno; return (unsigned long long) p[zidx]; }
49         default: assert(0);
50     }
51 }
52 
get_var_value(void * vdata,int datatype,int idx)53 static double get_var_value(void *vdata, int datatype, int idx)
54 {
55     switch (datatype)
56     {
57         case DB_INT: {int *p = (int*)vdata; return p[idx];}
58         case DB_FLOAT: {float *p = (float*)vdata; return p[idx];}
59         case DB_DOUBLE: {double *p = (double*)vdata; return p[idx];}
60         default: assert(0);
61     }
62 }
63 
genkey(DBucdmesh const * ucdm,string const & prefix,int dom,int zidx)64 static string genkey(DBucdmesh const* ucdm, string const& prefix, int dom, int zidx)
65 {
66     unsigned long long gzoneno = get_zoneid(ucdm->zones, zidx);
67     char tmp[256];
68     if (gzoneno != (unsigned long long)-1)
69     {
70         if (dom == -1)
71             sprintf(tmp, "%llx:%d", gzoneno, zidx);
72         else
73             sprintf(tmp, "%llx:%d:%d", gzoneno, dom, zidx);
74     }
75     else
76     {
77         if (dom == -1)
78             sprintf(tmp, "%d", zidx);
79         else
80             sprintf(tmp, "%d:%d", dom, zidx);
81     }
82     string zkey = prefix + ":" + string(tmp);
83     return zkey;
84 }
85 
86 static double retvals[256];
get_var_values(void ** vdata,int nvars,int datatype,int idx)87 static double *get_var_values(void **vdata, int nvars, int datatype, int idx)
88 {
89     for (int i = 0; i < nvars; i++)
90         retvals[i] = get_var_value(vdata[i], datatype, idx);
91     return retvals;
92 }
93 
stream_ucdvar(DBucdmesh const * ucdm,DBucdvar const * ucdv,string const & prefix,int dom,strmap_t & fmap)94 static void stream_ucdvar(DBucdmesh const *ucdm, DBucdvar const *ucdv, string const& prefix, int dom, strmap_t& fmap)
95 {
96     if (ucdv->centering == DB_ZONECENT)
97     {
98         for (int i = 0; i < ucdm->zones->nzones; i++)
99         {
100             string zkey = genkey(ucdm, prefix, dom, i);
101             double *vals = get_var_values(ucdv->vals, ucdv->nvals, ucdv->datatype, i);
102             for (int j = 0; j < ucdv->nvals; j++)
103             {
104                 char tmp[256];
105                 sprintf(tmp, "%s%1d=%f", ucdv->name, j, vals[j]);
106                 fmap[zkey] += string(tmp);
107                 if (j < ucdv->nvals-1) fmap[zkey] += ";";
108             }
109             fmap[zkey] += ":";
110         }
111     }
112     else if (ucdv->centering == DB_NODECENT)
113     {
114         int zlidx = 0;
115         int zidx = 0;
116         DBzonelist const *zl = ucdm->zones;
117         for (int i = 0; i < zl->nshapes; i++)
118         {
119             const int shapecnt = zl->shapecnt[i];
120             const int shapesize = zl->shapesize[i];
121             const int shapetype = zl->shapetype[i];
122             for (int j = 0; j < shapecnt; j++)
123             {
124                 char tmp[256];
125                 string zkey = genkey(ucdm, prefix, dom, zidx);
126                 for (int k = 0; k < shapesize; k++)
127                 {
128                     int nodeid = zl->nodelist[zlidx+k];
129                     double *vals = get_var_values(ucdv->vals, ucdv->nvals, ucdv->datatype, nodeid);
130                     for (int j = 0; j < ucdv->nvals; j++)
131                     {
132                         char tmp[256];
133                         sprintf(tmp, "%s%1d=%f", ucdv->name, j, vals[j]);
134                         fmap[zkey] += string(tmp);
135                         if (j < ucdv->nvals-1) fmap[zkey] += ";";
136                     }
137                     if (k < shapesize-1) fmap[zkey] += "$";
138                 }
139                 zlidx += shapesize;
140                 zidx++;
141                 fmap[zkey] += ":";
142             }
143         }
144     }
145     else
146     {
147         assert(0);
148     }
149 }
150 
stream_ucdmesh(DBucdmesh const * ucdm,string const & prefix,int dom,strmap_t & fmap)151 static void stream_ucdmesh(DBucdmesh const *ucdm, string const& prefix, int dom, strmap_t& fmap)
152 {
153     int zlidx = 0;
154     int zidx = 0;
155     DBzonelist const *zl = ucdm->zones;
156     for (int i = 0; i < zl->nshapes; i++)
157     {
158         const int shapecnt = zl->shapecnt[i];
159         const int shapesize = zl->shapesize[i];
160         const int shapetype = zl->shapetype[i];
161         for (int j = 0; j < shapecnt; j++)
162         {
163             // Zone key section
164             char tmp[256];
165             string zkey = genkey(ucdm, prefix, dom, zidx);
166             fmap[zkey] = "";
167             // nodes  section (probaly not necessary)
168             for (int k = 0; k < shapesize; k++)
169             {
170                 int nodeid = zl->nodelist[zlidx+k];
171                 sprintf(tmp, "n%1d=%d", k, nodeid);
172                 fmap[zkey] += string(tmp);
173                 if (k < shapesize-1) fmap[zkey] += ":";
174             }
175             fmap[zkey] += "|";
176             // coordinates section
177             for (int k = 0; k < shapesize; k++)
178             {
179                 int nodeid = zl->nodelist[zlidx+k];
180                 double x, y, z;
181                 get_coord(ucdm, nodeid, &x, &y, &z);
182                 sprintf(tmp, "x%1d=%f$y%1d=%f$z%1d=%f", k, x, k, y, k, z);
183                 fmap[zkey] += string(tmp);
184                 if (k < shapesize-1) fmap[zkey] += ":";
185             }
186             fmap[zkey] += "|";
187             zlidx += shapesize;
188             zidx++;
189         }
190     }
191 }
192 
stream_cwdir(DBfile * dbfile,string prefix,int dom,strmap_t & fmap)193 static void stream_cwdir(DBfile *dbfile, string prefix, int dom, strmap_t &fmap)
194 {
195     DBtoc *toc = DBGetToc (dbfile);
196 
197     for (int i = 0; i < toc->nucdmesh; i++)
198     {
199         DBucdmesh *m = DBGetUcdmesh(dbfile, toc->ucdmesh_names[i]);
200         string newprefix = prefix + "/" + string(toc->ucdmesh_names[i]);
201         stream_ucdmesh(m, newprefix, dom, fmap);
202         long oldmask = DBGetDataReadMask();
203         for (int j = 0; j < toc->nucdvar; j++)
204         {
205             DBSetDataReadMask(DBNone);
206             DBucdvar *v = DBGetUcdvar(dbfile, toc->ucdvar_names[j]);
207             if (!strcmp(v->meshname, toc->ucdmesh_names[i]))
208             {
209                 DBFreeUcdvar(v);
210                 DBSetDataReadMask(DBAll);
211                 v = DBGetUcdvar(dbfile, toc->ucdvar_names[j]);
212                 stream_ucdvar(m, v, newprefix, dom, fmap);
213                 DBFreeUcdvar(v);
214             }
215         }
216         DBSetDataReadMask(oldmask);
217         DBFreeUcdmesh(m);
218     }
219 
220     if (!toc->ndir) return;
221 
222     //
223     // Copy relevant info from the toc. Otherwise, it'll get lost on
224     // successive calls to DBSetDir().
225     //
226     int      norigdir      = toc->ndir;
227     char   **origdir_names = new char*[norigdir];
228     for (int i = 0 ; i < norigdir ; i++)
229     {
230         origdir_names[i] = new char[strlen(toc->dir_names[i])+1];
231         strcpy(origdir_names[i], toc->dir_names[i]);
232     }
233 
234     for (int i = 0; i <norigdir; i++)
235     {
236         int newdom;
237         int n = sscanf(origdir_names[i], "domain_%d", &newdom);
238         if (n != 1)
239             n = sscanf(origdir_names[i], "block%d", &newdom);
240         if (n != 1) continue;
241         string new_prefix = prefix + "/" + string(origdir_names[i]);
242         DBSetDir(dbfile, origdir_names[i]);
243         stream_cwdir(dbfile, new_prefix, newdom, fmap);
244         DBSetDir(dbfile, "..");
245     }
246 
247     for (int i = 0; i <norigdir; i++)
248         delete [] origdir_names[i];
249     delete [] origdir_names;
250 
251 }
252 
stream_file(char const * filename)253 static void stream_file(char const *filename)
254 {
255     DBfile *dbfile = DBOpen(filename, DB_UNKNOWN, DB_READ);
256     strmap_t stream_map;
257     stream_cwdir(dbfile, "", -1, stream_map);
258 
259     for (strmap_t::const_iterator cit = stream_map.begin(); cit != stream_map.end(); cit++)
260         cout << cit->first << "\t" << cit->second << endl;
261 }
262 
main(int argc,char ** argv)263 int main(int argc, char **argv)
264 {
265     char filename[1024];
266     char varname[256];
267 
268     filename[0] = '\0';
269     varname[0] = '\0';
270     for (int i = 0; i < argc; i++)
271     {
272         if (ARG_OPT(--fn))
273         {
274             i++;
275             assert(strlen(argv[i])<sizeof(filename));
276             strcpy(filename, argv[i]);
277         }
278         else if (ARG_OPT(--var))
279         {
280             i++;
281             assert(strlen(argv[i])<sizeof(varname));
282             strcpy(varname, argv[i]);
283         }
284     }
285 
286     if (!strcmp(filename, ""))
287     {
288         cerr << "filename not specified" << endl;
289         exit(1);
290     }
291 
292     stream_file(filename);
293 
294     return 0;
295 }
296