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, 1 month 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

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: eplus_adduvf.c,v 2.1 2014/02/09 05:49:21 greg Exp $";
3 #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 #include "rtprocess.h"
16
17 #ifndef NSAMPLES
18 #define NSAMPLES 100000 /* number of samples to use */
19 #endif
20
21 char *progname; /* global argv[0] */
22
23 char temp_octree[128]; /* temporary octree */
24
25 const char UVF_PNAME[] =
26 "ZoneProperty:UserViewFactor:bySurfaceName";
27
28 const char ADD_HEADER[] =
29 "!+++ User View Factors computed by Radiance +++!\n";
30
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 typedef struct s_zone {
45 const char *zname; /* zone name */
46 struct s_zone *next; /* next zone in list */
47 int nsurf; /* surface count */
48 IDF_PARAMETER *pfirst; /* first matching parameter */
49 IDF_PARAMETER *plast; /* last matching parameter */
50 } ZONE; /* a list of collected zone surfaces */
51
52 ZONE *zone_list = NULL; /* our list of zones */
53
54 IDF_LOADED *our_idf = NULL; /* loaded/modified IDF */
55
56 /* Create a new zone and push to top of our list */
57 static ZONE *
58 new_zone(const char *zname, IDF_PARAMETER *param)
59 {
60 ZONE *znew = (ZONE *)malloc(sizeof(ZONE));
61
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 znew->nsurf = 1;
68 return(zone_list = znew);
69 }
70
71 /* Add the detailed surface (polygon) to the named zone */
72 static ZONE *
73 add2zone(IDF_PARAMETER *param, const char *zname)
74 {
75 ZONE *zptr;
76
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 zptr->nsurf++;
87 return(zptr);
88 }
89
90 /* 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 /* Compute zone User View Factors */
208 static int
209 compute_zones(void)
210 {
211 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 }
236
237 /* Load IDF and compute User View Factors */
238 int
239 main(int argc, char *argv[])
240 {
241 int incl_comments = 1;
242 char *origIDF, *revIDF;
243 IDF_PARAMETER *pptr;
244 int i;
245
246 progname = argv[0];
247 if (argc > 2 && !strcmp(argv[1], "-c")) {
248 incl_comments = -1; /* output header only */
249 ++argv; --argc;
250 }
251 if ((argc < 2) | (argc > 3)) {
252 fputs("Usage: ", stderr);
253 fputs(progname, stderr);
254 fputs(" [-c] Model.idf [Revised.idf]\n", stderr);
255 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 fputs(progname, stderr);
263 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 fputs(progname, stderr);
272 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 fputs(progname, stderr);
291 fputs(": warning - missing zone field\n", stderr);
292 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 if (!idf_write(our_idf, revIDF, incl_comments)) {
302 fputs(progname, stderr);
303 fputs(": error writing IDF '", stderr);
304 fputs(revIDF, stderr);
305 fputs("'\n", stderr);
306 return(1);
307 }
308 return(0); /* finito! */
309 }