ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/util/eplus_adduvf.c
Revision: 2.2
Committed: Sun Feb 9 22:19:30 2014 UTC (10 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.1: +175 -18 lines
Log Message:
Partial implementation of eplus_adduvf

File Contents

# User Rev Content
1 greg 2.1 #ifndef lint
2 greg 2.2 static const char RCSid[] = "$Id: eplus_adduvf.c,v 2.1 2014/02/09 05:49:21 greg Exp $";
3 greg 2.1 #endif
4     /*
5     * Add User View Factors to EnergyPlus Input Data File
6     *
7     * G.Ward for LBNL
8     */
9    
10     #include <stdio.h>
11     #include <stdlib.h>
12     #include <string.h>
13     #include "eplus_idf.h"
14     #include "triangulate.h"
15 greg 2.2 #include "rtprocess.h"
16 greg 2.1
17     #ifndef NSAMPLES
18     #define NSAMPLES 100000 /* number of samples to use */
19     #endif
20    
21 greg 2.2 char *progname; /* global argv[0] */
22    
23     char temp_octree[128]; /* temporary octree */
24    
25     const char UVF_PNAME[] =
26     "ZoneProperty:UserViewFactor:bySurfaceName";
27 greg 2.1
28     const char ADD_HEADER[] =
29 greg 2.2 "!+++ User View Factors computed by Radiance +++!\n";
30 greg 2.1
31     #define NAME_FLD 1 /* name field always first? */
32    
33     typedef struct {
34     const char *pname; /* parameter type name */
35     short zone_fld; /* zone field index */
36     short vert_fld; /* vertex field index */
37     } SURF_PTYPE; /* surface type we're interested in */
38    
39     const SURF_PTYPE surf_type[] = {
40     {"BuildingSurface:Detailed", 4, 10},
41     {NULL}
42     };
43    
44 greg 2.2 typedef struct s_zone {
45 greg 2.1 const char *zname; /* zone name */
46     struct s_zone *next; /* next zone in list */
47 greg 2.2 int nsurf; /* surface count */
48 greg 2.1 IDF_PARAMETER *pfirst; /* first matching parameter */
49     IDF_PARAMETER *plast; /* last matching parameter */
50 greg 2.2 } ZONE; /* a list of collected zone surfaces */
51    
52     ZONE *zone_list = NULL; /* our list of zones */
53 greg 2.1
54     IDF_LOADED *our_idf = NULL; /* loaded/modified IDF */
55    
56     /* Create a new zone and push to top of our list */
57 greg 2.2 static ZONE *
58 greg 2.1 new_zone(const char *zname, IDF_PARAMETER *param)
59     {
60 greg 2.2 ZONE *znew = (ZONE *)malloc(sizeof(ZONE));
61 greg 2.1
62     if (znew == NULL)
63     return(NULL);
64     znew->zname = zname; /* assumes static */
65     znew->next = zone_list;
66     znew->pfirst = znew->plast = param;
67 greg 2.2 znew->nsurf = 1;
68 greg 2.1 return(zone_list = znew);
69     }
70    
71     /* Add the detailed surface (polygon) to the named zone */
72 greg 2.2 static ZONE *
73 greg 2.1 add2zone(IDF_PARAMETER *param, const char *zname)
74     {
75 greg 2.2 ZONE *zptr;
76 greg 2.1
77     for (zptr = zone_list; zptr != NULL; zptr = zptr->next)
78     if (!strcmp(zptr->zname, zname))
79     break;
80     if (zptr == NULL)
81     return(new_zone(zname, param));
82     /* keep surfaces together */
83     if (!idf_movparam(our_idf, param, zptr->plast))
84     return(NULL);
85     zptr->plast = param;
86 greg 2.2 zptr->nsurf++;
87 greg 2.1 return(zptr);
88     }
89    
90 greg 2.2 /* Determine if a parameter is a surface in the indicated zone */
91     static int
92     in_zone(IDF_PARAMETER *param, const char *zname)
93     {
94     int i = 0;
95     IDF_FIELD *fptr;
96     /* check for surface type */
97     while (strcmp(surf_type[i].pname, param->pname))
98     if (surf_type[++i].pname == NULL)
99     return(0);
100     /* get zone field */
101     fptr = idf_getfield(param, surf_type[i].zone_fld);
102     if (fptr == NULL)
103     return(0);
104     /* check for match */
105     if (strcmp(fptr->arg, zname))
106     return(0);
107     /* return field for #verts */
108     return(surf_type[i].vert_fld);
109     }
110    
111     /* Convert surface to Radiance with modifier based on unique name */
112     static int
113     rad_surface(const char *zname, IDF_PARAMETER *param, FILE *ofp)
114     {
115     const char *sname = idf_getfield(param, NAME_FLD)->arg;
116     IDF_FIELD *fptr = idf_getfield(param, in_zone(param, zname));
117     int nvert, i;
118    
119     if (fptr == NULL || (nvert = atoi(fptr->arg)) < 3) {
120     fprintf(stderr, "%s: bad surface '%s'\n", progname, sname);
121     return(0);
122     }
123     fprintf(ofp, "\nvoid glow '%s'\n0\n0\n4 1 1 1 0\n", sname);
124     fprintf(ofp, "\n'%s' polygon 's_%s'\n0\n0\n%d\n", sname, sname, 3*nvert);
125     while (nvert--) {
126     for (i = 3; i--; ) {
127     fptr = fptr->next;
128     if (fptr == NULL) {
129     fprintf(stderr,
130     "%s: missing vertex fields in surface '%s'\n",
131     progname, sname);
132     return(0);
133     }
134     fputc('\t', ofp);
135     fputs(fptr->arg, ofp);
136     }
137     fputc('\n', ofp);
138     }
139     return(!ferror(ofp));
140     }
141    
142     /* Strat rcontrib process */
143     static int
144     start_rcontrib(SUBPROC *pd, ZONE *zp)
145     {
146     #define BASE_AC 3
147     static char *base_av[BASE_AC] = {
148     "rcontrib", "-ff", "-h"
149     };
150     char cbuf[300];
151     char **av;
152     FILE *ofp;
153     IDF_PARAMETER *pptr;
154     int i, n;
155     /* start oconv command */
156     sprintf(cbuf, "oconv - > '%s'", temp_octree);
157     if ((ofp = popen(cbuf, "w")) == NULL) {
158     fputs(progname, stderr);
159     fputs(": cannot open oconv process\n", stderr);
160     return(0);
161     }
162     /* allocate argument list */
163     av = (char **)malloc(sizeof(char *)*(BASE_AC+4+2*zp->nsurf));
164     if (av == NULL)
165     return(0);
166     for (i = 0; i < BASE_AC; i++)
167     av[i] = base_av[i];
168     sprintf(cbuf, "%d", NSAMPLES);
169     av[i++] = "-c";
170     av[i++] = cbuf; /* add modifier arguments */
171     for (n = zp->nsurf, pptr = zp->pfirst; n--; pptr = pptr->dnext) {
172     IDF_FIELD *fptr = idf_getfield(pptr, NAME_FLD);
173     if (fptr == NULL) {
174     fputs(progname, stderr);
175     fputs(": missing name for surface parameter\n", stderr);
176     return(0);
177     }
178     av[i++] = "-m";
179     av[i++] = fptr->arg;
180     if (!rad_surface(zp->zname, pptr, ofp))
181     return(0);
182     }
183     if (pclose(ofp) != 0) { /* finish oconv */
184     fputs(progname, stderr);
185     fputs(": error running oconv process\n", stderr);
186     return(0);
187     }
188     av[i++] = temp_octree; /* add final octree argument */
189     av[i] = NULL;
190     if (!open_process(pd, av)) { /* start process */
191     fputs(progname, stderr);
192     fputs(": cannot start rcontrib process\n", stderr);
193     return(0);
194     }
195     free(av); /* all done -- clean up */
196     return(1);
197     #undef BASE_AC
198     }
199    
200     /* Compute User View Factors using open rcontrib process */
201     static int
202     compute_uvfs(SUBPROC *pd, ZONE *sp)
203     {
204    
205     }
206    
207 greg 2.1 /* Compute zone User View Factors */
208     static int
209     compute_zones(void)
210     {
211 greg 2.2 ZONE *zptr;
212     /* temporary octree name */
213     if (temp_filename(temp_octree, sizeof(temp_octree), TEMPLATE) == NULL) {
214     fputs(progname, stderr);
215     fputs(": cannot create temporary octree\n", stderr);
216     return(0);
217     }
218     /* compute each zone */
219     for (zptr = zone_list; zptr != NULL; zptr = zptr->next) {
220     SUBPROC rcproc;
221     /* start rcontrib process */
222     if (!start_rcontrib(&rcproc, zptr))
223     return(0);
224     /* compute+add view factors */
225     if (!compute_uvfs(&rcproc, zptr))
226     return(0);
227     if (close_process(&rcproc) != 0) {
228     fputs(progname, stderr);
229     fputs(": bad return status from rcontrib\n", stderr);
230     return(0);
231     }
232     }
233     unlink(temp_octree); /* remove octree file */
234     return(1);
235 greg 2.1 }
236    
237     /* Load IDF and compute User View Factors */
238     int
239     main(int argc, char *argv[])
240     {
241 greg 2.2 int incl_comments = 1;
242 greg 2.1 char *origIDF, *revIDF;
243     IDF_PARAMETER *pptr;
244     int i;
245    
246 greg 2.2 progname = argv[0];
247     if (argc > 2 && !strcmp(argv[1], "-c")) {
248     incl_comments = -1; /* output header only */
249     ++argv; --argc;
250     }
251 greg 2.1 if ((argc < 2) | (argc > 3)) {
252     fputs("Usage: ", stderr);
253 greg 2.2 fputs(progname, stderr);
254     fputs(" [-c] Model.idf [Revised.idf]\n", stderr);
255 greg 2.1 return(1);
256     }
257     origIDF = argv[1];
258     revIDF = (argc == 2) ? argv[1] : argv[2];
259     /* load Input Data File */
260     our_idf = idf_load(origIDF);
261     if (our_idf == NULL) {
262 greg 2.2 fputs(progname, stderr);
263 greg 2.1 fputs(": cannot load IDF '", stderr);
264     fputs(origIDF, stderr);
265     fputs("'\n", stderr);
266     return(1);
267     }
268     /* remove existing UVFs */
269     if ((pptr = idf_getparam(our_idf, UVF_PNAME)) != NULL) {
270     IDF_PARAMETER *pnext;
271 greg 2.2 fputs(progname, stderr);
272 greg 2.1 fputs(": removing previous User View Factors\n", stderr);
273     do {
274     pnext = pptr->pnext;
275     idf_delparam(our_idf, pptr);
276     } while (pnext != NULL);
277     }
278     /* add to header */
279     if (our_idf->hrem == NULL ||
280     (i = strlen(our_idf->hrem)-strlen(ADD_HEADER)) < 0 ||
281     strcmp(our_idf->hrem+i, ADD_HEADER))
282     idf_add2hdr(our_idf, ADD_HEADER);
283     /* gather zone surfaces */
284     for (i = 0; surf_type[i].pname != NULL; i++)
285     for (pptr = idf_getparam(our_idf, surf_type[i].pname);
286     pptr != NULL; pptr = pptr->pnext) {
287     IDF_FIELD *fptr = idf_getfield(pptr,
288     surf_type[i].zone_fld);
289     if (fptr == NULL) {
290 greg 2.2 fputs(progname, stderr);
291     fputs(": warning - missing zone field\n", stderr);
292 greg 2.1 continue;
293     }
294     if (add2zone(pptr, fptr->arg) == NULL)
295     return(1);
296     }
297     /* run rcontrib on each zone */
298     if (!compute_zones())
299     return(1);
300     /* write out modified IDF */
301 greg 2.2 if (!idf_write(our_idf, revIDF, incl_comments)) {
302     fputs(progname, stderr);
303 greg 2.1 fputs(": error writing IDF '", stderr);
304     fputs(revIDF, stderr);
305     fputs("'\n", stderr);
306     return(1);
307     }
308     return(0); /* finito! */
309     }