solstice-pp

Post-processing utilities for the solstice app
git clone git://git.meso-star.com/solstice-pp.git
Log | Files | Refs | README | LICENSE

commit dfc0c0db65930b49cebed1e799179407bd255d8f
parent 125de52f3b847bb10a3f04bd0b9fe0d8bb19380a
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Thu, 27 Jul 2017 14:42:43 +0200

The program do not rely on the Star-Engine anymore

Diffstat:
Msrc/Makefile | 7+++----
Msrc/solpath.c | 27++++-----------------------
Msrc/solpp.h | 504++++++++++++++++++++++++++++---------------------------------------------------
Msrc/solvtk.c | 230++++++++++++++++++++++++++++++++++++++-----------------------------------------
4 files changed, 295 insertions(+), 473 deletions(-)

diff --git a/src/Makefile b/src/Makefile @@ -13,17 +13,16 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -STAR_ENGINE=/home/moi/code/star-engine-solstice/local NEXPERIMENTS=100000 NPATHS=100 -SUN_DIRS=270,45:290,30:160,60 +SUN_DIRS=270,45 RCV=themis-rcv.yaml INPUT=themis.yaml GEOM=geom SIMUL=simul -CFLAGS = -O2 -std=c99 -pedantic -Wall +CFLAGS = -g -std=c99 -pedantic -Wall SCRIPT = themis.c solsplit.c solpp.c solvtk.c solpath.c PROG = $(SCRIPT:%.c=%) PATH := $(PATH):$(STAR_ENGINE)/bin:. @@ -53,7 +52,7 @@ clean: rm -rf $(PROG) $(INPUT) $(GEOM) $(SIMUL) $(RCV) *.obj *.vtk *simulation*.txt $(PROG): %: %.c solpp.h - $(CC) -o $@ $(CFLAGS) $< -I$(STAR_ENGINE)/include -L$(STAR_ENGINE)/lib -lrsys + $(CC) -o $@ $(CFLAGS) $< $(INPUT): $(PROG) themis > $@ diff --git a/src/solpath.c b/src/solpath.c @@ -13,32 +13,13 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#define CHK(Cond) if(!(Cond)) \ - {fprintf(stderr, "error:%s:%d\n", __FILE__, __LINE__); abort();} (void)0 - -struct buf { char* mem; size_t sz; }; - -static char* -read_line(struct buf* b, FILE* stream) -{ - if(!b->sz) b->mem = malloc((b->sz=32)); - if(!fgets(b->mem, (int)b->sz, stream)) return NULL; - while(!strrchr(b->mem, '\n') && !feof(stream)) { - b->mem = realloc(b->mem, (b->sz*=2)); - CHK(fgets(b->mem+strlen(b->mem), (int)(b->sz-strlen(b->mem)), stream)); - } - return b->mem; -} +#include "solpp.h" int main(int argc, char** argv) { char s[128]; - struct buf buf = {NULL, 0}; + buf_char_T buf = BUF_NULL; FILE* input = stdin; FILE* output = NULL; char* line = NULL; @@ -52,7 +33,7 @@ main(int argc, char** argv) while((line = read_line(&buf, input))) { if(strncmp(line, "#--- Sun direction:", 19)) { CHK(output != NULL); - CHK(fwrite(line, strlen(line), 1, output) == 1); + fprintf(output, "%s\n", line); } else { CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &azim, &elev) == 2); CHK(snprintf(s, sizeof(s), "%g-%g-paths.vtk", azim, elev) < sizeof(s)); @@ -60,7 +41,7 @@ main(int argc, char** argv) CHK(output = fopen(s, "w")); } } - if(buf.mem) free(buf.mem); + BUF_RELEASE(buf); if(output) fclose(output); return 0; } diff --git a/src/solpp.h b/src/solpp.h @@ -13,41 +13,72 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#define _POSIX_C_SOURCE 200809L /* Support of strdup */ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + #ifndef SOLPP_H #define SOLPP_H -#include <rsys/dynamic_array.h> -#include <rsys/str.h> -#include <rsys/stretchy_array.h> +enum side { FRONT, BACK }; +struct mc { double E/* Expected value */, SE/* Standard Error */; }; -enum side { - FRONT, - BACK -}; +/******************************************************************************* + * Helper macros + ******************************************************************************/ +#define STR__(X) #X +#define STR(X) STR__(X) -struct mc { - double E; /* Expected value */ - double SE; /* Standard Error */ -}; -static struct mc MC_ZERO = {0,0}; +#define FOR_EACH(Id, Start, End) for((Id)=(Start); (Id)<(End); ++(Id)) -#define DARRAY_NAME mc -#define DARRAY_DATA struct mc -#include <rsys/dynamic_array.h> +#define CHK(Cond) if(!(Cond)) \ + {fprintf(stderr, "error:%s:%d\n", __FILE__, __LINE__); abort();} (void)0 -static INLINE char* -read_line(char** b, FILE* stream) +/******************************************************************************* + * Dynamic buffer + ******************************************************************************/ +#define BUF(Type) struct { Type* mem; size_t ca; size_t sz; } +#define BUF_NULL {NULL, 0, 0} +#define BUF_RELEASE(B) free((B).mem) +#define BUF_RESERVE(B, Sz) \ + if((Sz)>(B).ca) { \ + CHK((B).mem = realloc((B).mem, sizeof(*(B).mem)*((B).ca=(Sz)))); \ + } (void)0 +#define BUF_RESIZE(B, Sz) {BUF_RESERVE((B), Sz); (B).sz = Sz;} (void)0 +#define BUF_PUSH(B, E) { \ + if((B).sz >= (B).ca) BUF_RESERVE((B), ((B).ca?(B).ca*2:32)); \ + (B).mem[(B).sz++]=(E); \ +} (void)0 +#define BUF_SZ(B) (B).sz +#define BUF_MEM(B) (B).mem +#define BUF_AT(B, I) (B).mem[I] + +/******************************************************************************* + * Helper function + ******************************************************************************/ +typedef BUF(char) buf_char_T; + +static inline char* +read_line(buf_char_T* b, FILE* stream) { - if(!*b) *b = sa_add(*b, 32); - if(!fgets(*b, (int)sa_size(*b), stream)) return NULL; + char* c; + + if(!BUF_SZ(*b)) BUF_RESIZE(*b, 32); + if(!fgets(BUF_MEM(*b), (int)BUF_SZ(*b), stream)) return NULL; + /* Ensure that the whole line is read */ - while(!strrchr(*b, '\n') && !feof(stream)) { - NCHECK(sa_add(*b, 32), NULL); - NCHECK(fgets(*b+strlen(*b), (int)(sa_size(*b)-strlen(*b)), stream), NULL); + while(!strrchr(BUF_MEM(*b), '\n') && !feof(stream)) { + BUF_RESIZE(*b, BUF_SZ(*b)+32); + CHK(fgets + (BUF_MEM(*b) + strlen(BUF_MEM(*b)), + (int)(BUF_SZ(*b) - strlen(BUF_MEM(*b))), stream)); } + /* Remove the carriage return */ - if((*b)[strlen(*b)-1] == '\n') (*b)[strlen(*b)-1] = '\0'; - return *b; + if((c = strrchr(BUF_MEM(*b), '\n'))) *c = '\0'; + + return BUF_MEM(*b); } /******************************************************************************* @@ -59,131 +90,33 @@ struct rcv { struct mc reflectivity_loss[2]; struct mc absorptivity_loss[2]; struct mc efficiency[2]; - struct darray_mc map[2]; - struct str name; + BUF(struct mc) map[2]; + char* name; size_t id; double area; }; -static INLINE void -rcv_init(struct mem_allocator* allocator, struct rcv* rcv) -{ - memset(rcv, 0, sizeof(struct rcv)); - str_init(allocator, &rcv->name); - darray_mc_init(allocator, &rcv->map[0]); - darray_mc_init(allocator, &rcv->map[1]); -} - -static INLINE void -rcv_release(struct rcv* rcv) +static inline void rcv_init(struct rcv* r) {memset(r, 0, sizeof(*r));} +static inline void rcv_release(struct rcv* r) { - str_release(&rcv->name); - darray_mc_release(&rcv->map[0]); - darray_mc_release(&rcv->map[1]); + free(r->name); + BUF_RELEASE(r->map[0]); + BUF_RELEASE(r->map[1]); } -static INLINE res_T -rcv_copy(struct rcv* dst, const struct rcv* src) -{ - int i; - if(dst == src) return RES_OK; - FOR_EACH(i, 0, 2) { - dst->absorbed_irradiance[i] = src->absorbed_irradiance[i]; - dst->irradiance[i] = src->irradiance[i]; - dst->reflectivity_loss[i] = src->reflectivity_loss[i]; - dst->absorptivity_loss[i] = src->absorptivity_loss[i]; - dst->efficiency[i] = src->efficiency[i]; - CHECK(darray_mc_copy(&dst->map[i], &src->map[i]), RES_OK); - } - dst->area = src->area; - CHECK(str_copy(&dst->name, &src->name), RES_OK); - return RES_OK; -} - -static INLINE res_T -rcv_copy_and_release(struct rcv* dst, struct rcv* src) -{ - int i; - if(dst == src) return RES_OK; - FOR_EACH(i, 0, 2) { - dst->absorbed_irradiance[i] = src->absorbed_irradiance[i]; - dst->irradiance[i] = src->irradiance[i]; - dst->reflectivity_loss[i] = src->reflectivity_loss[i]; - dst->absorptivity_loss[i] = src->absorptivity_loss[i]; - dst->efficiency[i] = src->efficiency[i]; - CHECK(darray_mc_copy_and_release(&dst->map[i], &src->map[i]), RES_OK); - } - dst->area = src->area; - CHECK(str_copy_and_release(&dst->name, &src->name), RES_OK); - return RES_OK; -} - -#define DARRAY_NAME rcv -#define DARRAY_DATA struct rcv -#define DARRAY_FUNCTOR_INIT rcv_init -#define DARRAY_FUNCTOR_RELEASE rcv_release -#define DARRAY_FUNCTOR_COPY rcv_copy -#define DARRAY_FUNCTOR_COPY_AND_RELEASE rcv_copy_and_release -#include <rsys/dynamic_array.h> - /******************************************************************************* * Per primary estimations ******************************************************************************/ struct prim { struct mc cos_factor; struct mc shadow_loss; - struct str name; + char* name; size_t id; size_t nsamps; double area; }; - -static INLINE void -prim_init(struct mem_allocator* allocator, struct prim* prim) -{ - memset(prim, 0, sizeof(struct prim)); - str_init(allocator, &prim->name); -} - -static INLINE void -prim_release(struct prim* prim) -{ - str_release(&prim->name); -} - -static INLINE res_T -prim_copy(struct prim* dst, const struct prim* src) -{ - if(dst == src) return RES_OK; - dst->cos_factor = src->cos_factor; - dst->shadow_loss = src->cos_factor; - dst->id = src->id; - dst->nsamps = src->nsamps; - dst->area = src->area; - CHECK(str_copy(&dst->name, &src->name), RES_OK); - return RES_OK; -} - -static INLINE res_T -prim_copy_and_release(struct prim* dst, struct prim* src) -{ - if(dst == src) return RES_OK; - dst->cos_factor = src->cos_factor; - dst->shadow_loss = src->cos_factor; - dst->id = src->id; - dst->nsamps = src->nsamps; - dst->area = src->area; - CHECK(str_copy_and_release(&dst->name, &src->name), RES_OK); - return RES_OK; -} - -#define DARRAY_NAME prim -#define DARRAY_DATA struct prim -#define DARRAY_FUNCTOR_INIT prim_init -#define DARRAY_FUNCTOR_RELEASE prim_release -#define DARRAY_FUNCTOR_COPY prim_copy -#define DARRAY_FUNCTOR_COPY_AND_RELEASE prim_copy_and_release -#include <rsys/dynamic_array.h> +static inline void prim_init(struct prim* p) {memset(p, 0, sizeof(*p));} +static inline void prim_release(struct prim* p) {free(p->name);} /******************************************************************************* * Per receiver X primary estimations @@ -196,10 +129,8 @@ struct rcvXprim { size_t rcv_id; size_t prim_id; }; - -#define DARRAY_NAME rcvXprim -#define DARRAY_DATA struct rcvXprim -#include <rsys/dynamic_array.h> +static inline void rcvXprim_init(struct rcvXprim* r) {memset(r, 0, sizeof(*r));} +static inline void rcvXprim_release(struct rcvXprim* r) { /*Do nothing*/} /******************************************************************************* * Overall estimations of a simulation @@ -213,157 +144,133 @@ struct simul { struct mc reflectivity_loss; struct mc absorptivity_loss; - struct darray_rcv rcvs; - struct darray_prim prims; - struct darray_rcvXprim rcvXprims; + BUF(struct rcv) rcvs; + BUF(struct prim) prims; + BUF(struct rcvXprim) rcvXprims; double azimuth; double elevation; size_t nsamps; }; -static INLINE void -simul_init(struct mem_allocator* allocator, struct simul* simul) +static inline void simul_init(struct simul* s) {memset(s, 0, sizeof(*s));} + +static inline void +simul_release(struct simul* s) { - darray_rcv_init(allocator, &simul->rcvs); - darray_prim_init(allocator, &simul->prims); - darray_rcvXprim_init(allocator, &simul->rcvXprims); - simul->azimuth = -1; - simul->elevation = -1; - simul->nsamps = 0; + size_t i; + FOR_EACH(i,0,BUF_SZ(s->rcvs)) rcv_release(&BUF_AT(s->rcvs, i)); + FOR_EACH(i,0,BUF_SZ(s->prims)) prim_release(&BUF_AT(s->prims, i)); + FOR_EACH(i,0,BUF_SZ(s->rcvXprims)) rcvXprim_release(&BUF_AT(s->rcvXprims, i)); + BUF_RELEASE(s->rcvs); + BUF_RELEASE(s->prims); + BUF_RELEASE(s->rcvXprims); } -static INLINE void -simul_release(struct simul* simul) +/******************************************************************************* + * Look for entities + ******************************************************************************/ +static inline struct prim* +find_primary(struct simul* s, const char* name) { - darray_rcv_release(&simul->rcvs); - darray_prim_release(&simul->prims); - darray_rcvXprim_release(&simul->rcvXprims); + size_t i; + FOR_EACH(i, 0, BUF_SZ(s->prims)) + if(!strcmp(BUF_AT(s->prims, i).name, name)) return &BUF_AT(s->prims, i); + return NULL; } -static INLINE res_T -simul_copy(struct simul* dst, const struct simul* src) +static inline struct prim* +find_primary_by_id(struct simul* s, const size_t id) { - dst->potential_irradiance = src->potential_irradiance; - dst->absorbed_irradiance = src->absorbed_irradiance; - dst->cos_factor = src->cos_factor; - dst->shadow_loss = src->shadow_loss; - dst->missing_loss = src->missing_loss; - dst->reflectivity_loss = src->reflectivity_loss; - dst->absorptivity_loss = src->absorptivity_loss; - CHECK(darray_rcv_copy(&dst->rcvs, &src->rcvs), RES_OK); - CHECK(darray_prim_copy(&dst->prims, &src->prims), RES_OK); - CHECK(darray_rcvXprim_copy(&dst->rcvXprims, &src->rcvXprims), RES_OK); - dst->azimuth = src->azimuth; - dst->elevation = src->elevation; - dst->nsamps = src->nsamps; - return RES_OK; + size_t i; + FOR_EACH(i, 0, BUF_SZ(s->prims)) + if(BUF_AT(s->prims, i).id == id) return &BUF_AT(s->prims, i); + return NULL; } -static INLINE res_T -simul_copy_and_release(struct simul* dst, struct simul* src) +static inline struct rcv* +find_receiver(struct simul* s, const char* name) { - dst->potential_irradiance = src->potential_irradiance; - dst->absorbed_irradiance = src->absorbed_irradiance; - dst->cos_factor = src->cos_factor; - dst->shadow_loss = src->shadow_loss; - dst->missing_loss = src->missing_loss; - dst->reflectivity_loss = src->reflectivity_loss; - dst->absorptivity_loss = src->absorptivity_loss; - CHECK(darray_rcv_copy_and_release(&dst->rcvs, &src->rcvs), RES_OK); - CHECK(darray_prim_copy_and_release(&dst->prims, &src->prims), RES_OK); - CHECK(darray_rcvXprim_copy_and_release(&dst->rcvXprims, &src->rcvXprims), RES_OK); - dst->azimuth = src->azimuth; - dst->elevation = src->elevation; - dst->nsamps = src->nsamps; - return RES_OK; + size_t i; + FOR_EACH(i, 0, BUF_SZ(s->rcvs)) + if(!strcmp(BUF_AT(s->rcvs, i).name, name)) return &BUF_AT(s->rcvs, i); + return NULL; } -static INLINE void -simul_clear(struct simul* simul) +static inline struct rcv* +find_receiver_by_id(struct simul* s, const size_t id) { - simul->potential_irradiance = MC_ZERO; - simul->absorbed_irradiance = MC_ZERO; - simul->cos_factor = MC_ZERO; - simul->shadow_loss = MC_ZERO; - simul->missing_loss = MC_ZERO; - simul->reflectivity_loss = MC_ZERO; - simul->absorptivity_loss = MC_ZERO; - darray_rcv_clear(&simul->rcvs); - darray_prim_clear(&simul->prims); - darray_rcvXprim_clear(&simul->rcvXprims); - simul->azimuth = -1; - simul->elevation = -1; - simul->nsamps = 0; + size_t i; + FOR_EACH(i, 0, BUF_SZ(s->rcvs)) + if(BUF_AT(s->rcvs, i).id == id) return &BUF_AT(s->rcvs, i); + return NULL; } -#define DARRAY_NAME simul -#define DARRAY_DATA struct simul -#define DARRAY_FUNCTOR_INIT simul_init -#define DARRAY_FUNCTOR_RELEASE simul_release -#define DARRAY_FUNCTOR_COPY_AND_RELEASE simul_copy_and_release -#include <rsys/dynamic_array.h> +static inline struct rcvXprim* +find_rcvXprim(struct simul* s, const size_t rcv_id, const size_t prim_id) +{ + size_t i; + FOR_EACH(i, 0, BUF_SZ(s->rcvXprims)) { + struct rcvXprim* rXp = &BUF_AT(s->rcvXprims, i); + if(rXp->rcv_id == rcv_id && rXp->prim_id == prim_id) return rXp; + } + return NULL; +} -static void +/******************************************************************************* + * Read simulation data from a solstice-output + ******************************************************************************/ +static inline void read_receiver_map_side_data(struct rcv* rcv, const size_t n, FILE* input) { - char* buf = NULL; + buf_char_T buf = BUF_NULL; char* line = NULL; size_t i; enum side side; - NCHECK(line = read_line(&buf, input), NULL); + CHK(line = read_line(&buf, input)); if(!strncmp(line+8, "Front_faces", 5)) side = FRONT; else if(!strncmp(line+8, "Back_faces",4)) side = BACK; - else FATAL("Unexpected side name\n"); + else { fprintf(stderr, "Unexpected side name\n"); abort(); } - NCHECK(read_line(&buf, input), NULL); /* LUT */ + CHK(read_line(&buf, input)); - CHECK(darray_mc_resize(&rcv->map[side], n), RES_OK); + BUF_RESIZE(rcv->map[side], n); FOR_EACH(i, 0, n) { - struct mc* mc = darray_mc_data_get(&rcv->map[side])+i; - NCHECK(line = read_line(&buf, input), NULL); - CHECK(sscanf(line, "%lf %lf", &mc->E, &mc->SE), 2); + struct mc* mc = &BUF_AT(rcv->map[side], i); + CHK(line = read_line(&buf, input)); + CHK(sscanf(line, "%lf %lf", &mc->E, &mc->SE) == 2); } - sa_release(buf); + BUF_RELEASE(buf); } -static void +static inline void read_receiver_map(struct simul* simul, FILE* input) { struct rcv* rcv; - char* buf = NULL; + buf_char_T buf = BUF_NULL; char* line = NULL; size_t i, n; long fp; - NCHECK(line = read_line(&buf, input), NULL); - FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { - rcv = darray_rcv_data_get(&simul->rcvs)+i; - if(!strcmp(str_cget(&rcv->name), line)) break; - rcv = NULL; - } - NCHECK(rcv, NULL); + CHK(line = read_line(&buf, input)); + CHK(rcv = find_receiver(simul, line)); /* Skip header */ - NCHECK(read_line(&buf, input), NULL); - NCHECK(read_line(&buf, input), NULL); - + CHK(read_line(&buf, input)); + CHK(read_line(&buf, input)); /* Skip vertices */ - NCHECK(line = read_line(&buf, input), NULL); - CHECK(sscanf(line, "POINTS %zu float", &n), 1); - FOR_EACH(i, 0, n) NCHECK(read_line(&buf, input), NULL); - + CHK(line = read_line(&buf, input)); + CHK(sscanf(line, "POINTS %zu float", &n) == 1); + FOR_EACH(i, 0, n) CHK(read_line(&buf, input)); /* Skip polygons */ - NCHECK(line = read_line(&buf, input), NULL); - CHECK(sscanf(line, "POLYGONS %zu %*u", &n), 1); - FOR_EACH(i, 0, n) NCHECK(read_line(&buf, input), NULL); - + CHK(line = read_line(&buf, input)); + CHK(sscanf(line, "POLYGONS %zu %*u", &n) == 1); + FOR_EACH(i, 0, n) CHK(read_line(&buf, input)); /* Read the map data of one side */ - NCHECK(line = read_line(&buf, input), NULL); - CHECK(sscanf(line, "CELL_DATA %zu", &n), 1); - + CHK(line = read_line(&buf, input)); + CHK(sscanf(line, "CELL_DATA %zu", &n) == 1); read_receiver_map_side_data(rcv, n, input); fp = ftell(input); @@ -373,27 +280,26 @@ read_receiver_map(struct simul* simul, FILE* input) if(line && !strncmp(line, "SCALAR", 6)) { read_receiver_map_side_data(rcv, n, input); } - - sa_release(buf); + BUF_RELEASE(buf); } -static INLINE void +static inline void read_simulation(struct simul* simul, FILE* input) { - char* buf = NULL; + buf_char_T buf = BUF_NULL; char* line = NULL; char* tk = NULL; size_t nrcvs, nprims; size_t i; /* Counters */ - NCHECK(line = read_line(&buf, input), NULL); - CHECK(sscanf(line, "%*u %zu %zu %zu %*u", &nrcvs, &nprims, &simul->nsamps), 3); + CHK(line = read_line(&buf, input)); + CHK(sscanf(line, "%*u %zu %zu %zu %*u", &nrcvs, &nprims, &simul->nsamps)==3); /* Global results */ #define READ(Name) { \ - NCHECK(line = read_line(&buf, input), NULL); \ - CHECK(sscanf(line, "%lf %lf", &simul->Name.E, &simul->Name.SE), 2); \ + CHK(line = read_line(&buf, input)); \ + CHK(sscanf(line, "%lf %lf", &simul->Name.E, &simul->Name.SE) == 2); \ } (void)0 READ(potential_irradiance); READ(absorbed_irradiance); @@ -405,17 +311,18 @@ read_simulation(struct simul* simul, FILE* input) #undef READ /* Read per receiver results */ - CHECK(darray_rcv_resize(&simul->rcvs, nrcvs), RES_OK); + BUF_RESIZE(simul->rcvs, nrcvs); FOR_EACH(i, 0, nrcvs) { - struct rcv* rcv = darray_rcv_data_get(&simul->rcvs) + i; + struct rcv* rcv = &BUF_AT(simul->rcvs, i); + rcv_init(rcv); - NCHECK(line = read_line(&buf, input), NULL); - NCHECK(tk = strtok(line, " \t"), NULL); - CHECK(str_set(&rcv->name, tk), RES_OK); + CHK(line = read_line(&buf, input)); + CHK(tk = strtok(line, " \t")); + CHK(rcv->name = strdup(tk)); - NCHECK(tk = strtok(NULL, ""), NULL); + CHK(tk = strtok(NULL, "")); #define GET(Side, Name) &rcv->Name[Side].E, &rcv->Name[Side].SE - CHECK(sscanf + CHK(sscanf (tk, "%zu %lf " "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf " @@ -430,34 +337,36 @@ read_simulation(struct simul* simul, FILE* input) GET(BACK, irradiance), GET(BACK, reflectivity_loss), GET(BACK, absorptivity_loss), - GET(BACK, efficiency)), 22); + GET(BACK, efficiency)) == 22); #undef GET } /* Read per primary results */ - CHECK(darray_prim_resize(&simul->prims, nprims), RES_OK); + BUF_RESIZE(simul->prims, nprims); FOR_EACH(i, 0, nprims) { - struct prim* prim = darray_prim_data_get(&simul->prims) + i; + struct prim* prim = &BUF_AT(simul->prims, i); + prim_init(prim); - NCHECK(line = read_line(&buf, input), NULL); - NCHECK(tk = strtok(line, " \t"), NULL); - CHECK(str_set(&prim->name, tk), RES_OK); + CHK(line = read_line(&buf, input)); + CHK(tk = strtok(line, " \t")); + CHK(prim->name = strdup(tk)); - NCHECK(tk = strtok(NULL, ""), NULL); - CHECK(sscanf(tk, "%zu %lf %zu %lf %lf %lf %lf", + CHK(tk = strtok(NULL, "")); + CHK(sscanf(tk, "%zu %lf %zu %lf %lf %lf %lf", &prim->id, &prim->area, &prim->nsamps, &prim->cos_factor.E, &prim->cos_factor.SE, - &prim->shadow_loss.E, &prim->shadow_loss.SE), 7); + &prim->shadow_loss.E, &prim->shadow_loss.SE) == 7); } /* Per receiverXprimary results */ - CHECK(darray_rcvXprim_resize(&simul->rcvXprims, nprims*nrcvs), RES_OK); + BUF_RESIZE(simul->rcvXprims, nprims*nrcvs); FOR_EACH(i, 0, nprims*nrcvs) { - struct rcvXprim* rcvXprim = darray_rcvXprim_data_get(&simul->rcvXprims) + i; + struct rcvXprim* rcvXprim = &BUF_AT(simul->rcvXprims, i); + rcvXprim_init(rcvXprim); - NCHECK(line = read_line(&buf, input), NULL); + CHK(line = read_line(&buf, input)); #define GET(Side, Name) &rcvXprim->Name[Side].E, &rcvXprim->Name[Side].SE - CHECK(sscanf + CHK(sscanf (line, "%zu %zu " "%lf %lf %lf %lf %lf %lf %lf %lf " @@ -470,7 +379,7 @@ read_simulation(struct simul* simul, FILE* input) GET(BACK, absorbed_irradiance), GET(BACK, irradiance), GET(BACK, reflectivity_loss), - GET(BACK, absorptivity_loss)), 18); + GET(BACK, absorptivity_loss)) == 18); #undef GET } @@ -486,66 +395,7 @@ read_simulation(struct simul* simul, FILE* input) break; } } - - sa_release(buf); -} - -static INLINE const struct prim* -find_primary(const struct simul* simul, const char* name) -{ - size_t i; - FOR_EACH(i, 0, darray_prim_size_get(&simul->prims)) { - const struct prim* prim = darray_prim_cdata_get(&simul->prims)+i; - if(!strcmp(str_cget(&prim->name), name)) return prim; - } - return NULL; -} - -static INLINE const struct prim* -find_primary_by_id(const struct simul* simul, const size_t id) -{ - size_t i; - FOR_EACH(i, 0, darray_prim_size_get(&simul->prims)) { - const struct prim* prim = darray_prim_cdata_get(&simul->prims)+i; - if(prim->id == id) return prim; - } - return NULL; -} - -static INLINE const struct rcv* -find_receiver(const struct simul* simul, const char* name) -{ - size_t i; - FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { - const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+i; - if(!strcmp(str_cget(&rcv->name), name)) return rcv; - } - return NULL; -} - -static INLINE const struct rcv* -find_receiver_by_id(const struct simul* simul, const size_t id) -{ - size_t i; - FOR_EACH(i, 0, darray_rcv_size_get(&simul->rcvs)) { - const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+i; - if(rcv->id == id) return rcv; - } - return NULL; -} - -static INLINE const struct rcvXprim* -find_rcvXprim - (const struct simul* simul, const size_t rcv_id, const size_t prim_id) -{ - size_t i; - FOR_EACH(i, 0, darray_rcvXprim_size_get(&simul->rcvXprims)) { - const struct rcvXprim* rcvXprim; - rcvXprim = darray_rcvXprim_cdata_get(&simul->rcvXprims)+i; - if(rcvXprim->rcv_id == rcv_id && rcvXprim->prim_id == prim_id) - return rcvXprim; - } - return NULL; + BUF_RELEASE(buf); } #endif /* SOLPP_H */ diff --git a/src/solvtk.c b/src/solvtk.c @@ -14,31 +14,28 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "solpp.h" -#include <rsys/str.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> struct mesh { - double* coords; - size_t* ids; - size_t* entities; - size_t* ncells; + + BUF(double) coords; + BUF(size_t) ids; + BUF(size_t) entities; + BUF(size_t) ncells; size_t voffset; }; -static const struct mesh MESH_NULL = {NULL, NULL, NULL, NULL, 0}; +static const struct mesh MESH_NULL = {BUF_NULL, BUF_NULL, BUF_NULL, BUF_NULL, 0}; -static void +static inline void mesh_release(struct mesh* msh) { - sa_release(msh->coords); - sa_release(msh->ids); - sa_release(msh->entities); - sa_release(msh->ncells); + BUF_RELEASE(msh->coords); + BUF_RELEASE(msh->ids); + BUF_RELEASE(msh->entities); + BUF_RELEASE(msh->ncells); memset(msh, 0, sizeof(struct mesh)); } -static void +static inline void mesh_write_vtk(FILE* output, struct mesh* msh) { size_t i, n; @@ -48,85 +45,90 @@ mesh_write_vtk(FILE* output, struct mesh* msh) fprintf(output, "ASCII\n"); fprintf(output, "DATASET POLYDATA\n"); - n = sa_size(msh->coords)/3; + n = BUF_SZ(msh->coords)/3; fprintf(output, "POINTS %zu float\n", n); FOR_EACH(i, 0, n) { - fprintf(output, "%g %g %g\n", SPLIT3(msh->coords + i*3)); + fprintf(output, "%g %g %g\n", + BUF_AT(msh->coords, i*3+0), + BUF_AT(msh->coords, i*3+1), + BUF_AT(msh->coords, i*3+2)); } - - n = sa_size(msh->ids)/3; + n = BUF_SZ(msh->ids)/3; fprintf(output, "POLYGONS %zu %zu\n", n, n*4); FOR_EACH(i, 0, n) { - fprintf(output, "3 %zu %zu %zu\n", SPLIT3(msh->ids + i*3)); + fprintf(output, "3 %zu %zu %zu\n", + BUF_AT(msh->ids, i*3+0), + BUF_AT(msh->ids, i*3+1), + BUF_AT(msh->ids, i*3+2)); } } -static void +static inline void mesh_write_obj(FILE* output, struct mesh* msh) { size_t i, n; - n = sa_size(msh->coords)/3; + n = BUF_SZ(msh->coords)/3; FOR_EACH(i, 0, n) { - fprintf(output, "v %g %g %g\n", SPLIT3(msh->coords + i*3)); + fprintf(output, "v %g %g %g\n", + BUF_AT(msh->coords, i*3+0), + BUF_AT(msh->coords, i*3+1), + BUF_AT(msh->coords, i*3+2)); } - n = sa_size(msh->ids)/3; + n = BUF_SZ(msh->ids)/3; FOR_EACH(i, 0, n) { fprintf(output, "f %zu %zu %zu\n", - msh->ids[i*3+0] + 1, - msh->ids[i*3+1] + 1, - msh->ids[i*3+2] + 1); + BUF_AT(msh->ids, i*3+0) + 1, + BUF_AT(msh->ids, i*3+1) + 1, + BUF_AT(msh->ids, i*3+2) + 1); } } -static void +static inline void mesh_write_prim_data_vtk - (FILE* output, const struct mesh* msh, const struct simul* simul) + (FILE* output, const struct mesh* msh, struct simul* simul) { - const struct prim* prim; - const struct rcvXprim* rcvXprim; + struct prim* prim; + struct rcvXprim* rcvXprim; size_t ircv; size_t iprim; size_t icell; size_t n; - n = sa_size(msh->ids) / 3; + n = BUF_SZ(msh->ids) / 3; fprintf(output, "CELL_DATA %zu\n", n); - fprintf(output, "FIELD PrimaryData %zu\n", - 2 + darray_rcv_size_get(&simul->rcvs)*8); + fprintf(output, "FIELD PrimaryData %zu\n", 2 + BUF_SZ(simul->rcvs)*8); fprintf(output, "cos_factor 2 %zu float\n", n); - FOR_EACH(iprim, 0, sa_size(msh->entities)) { - NCHECK(prim = find_primary_by_id(simul, msh->entities[iprim]), NULL); - FOR_EACH(icell, 0, msh->ncells[iprim]) { + FOR_EACH(iprim, 0, BUF_SZ(msh->entities)) { + CHK(prim = find_primary_by_id(simul, BUF_AT(msh->entities, iprim))); + FOR_EACH(icell, 0, BUF_AT(msh->ncells, iprim)) { fprintf(output, "%g %g\n", prim->cos_factor.E, prim->cos_factor.SE); } } fprintf(output, "shadow_loss 2 %zu float\n", n); - FOR_EACH(iprim, 0, sa_size(msh->entities)) { - NCHECK(prim = find_primary_by_id(simul, msh->entities[iprim]), NULL); - FOR_EACH(icell, 0, msh->ncells[iprim]) { + FOR_EACH(iprim, 0, BUF_SZ(msh->entities)) { + CHK(prim = find_primary_by_id(simul, BUF_AT(msh->entities, iprim))); + FOR_EACH(icell, 0, BUF_AT(msh->ncells, iprim)) { fprintf(output, "%g %g\n", prim->shadow_loss.E, prim->shadow_loss.SE); } } #define WRITE(Side, Name) { \ - fprintf(output, "%s_"STR(Side)"_"STR(Name)" 2 %zu float\n", \ - str_cget(&rcv->name), n); \ - FOR_EACH(iprim, 0, sa_size(msh->entities)) { \ - rcvXprim = find_rcvXprim(simul, rcv->id, msh->entities[iprim]); \ - NCHECK(rcvXprim, NULL); \ - FOR_EACH(icell, 0, msh->ncells[iprim]) { \ + fprintf(output, "%s_"STR(Side)"_"STR(Name)" 2 %zu float\n", rcv->name, n); \ + FOR_EACH(iprim, 0, BUF_SZ(msh->entities)) { \ + CHK(rcvXprim = find_rcvXprim(simul,rcv->id,BUF_AT(msh->entities,iprim)));\ + FOR_EACH(icell, 0, BUF_AT(msh->ncells, iprim)) { \ fprintf(output, "%g %g\n", \ rcvXprim->Name[Side].E, \ rcvXprim->Name[Side].SE); \ } \ } \ } (void)0 - FOR_EACH(ircv, 0, darray_rcv_size_get(&simul->rcvs)) { - const struct rcv* rcv = darray_rcv_cdata_get(&simul->rcvs)+ircv; + FOR_EACH(ircv, 0, BUF_SZ(simul->rcvs)) { + const struct rcv* rcv = &BUF_AT(simul->rcvs, ircv); WRITE(FRONT, absorbed_irradiance); WRITE(FRONT, irradiance); WRITE(FRONT, reflectivity_loss); @@ -139,25 +141,24 @@ mesh_write_prim_data_vtk #undef WRITE } -static void +static inline void mesh_write_rcv_data_vtk - (FILE* output, const struct mesh* msh, const struct simul* simul) + (FILE* output, const struct mesh* msh, struct simul* simul) { - const struct rcv* rcv; + struct rcv* rcv; size_t ircv; size_t icell; size_t n; - n = sa_size(msh->ids)/3; + n = BUF_SZ(msh->ids)/3; fprintf(output, "CELL_DATA %zu\n", n); - fprintf(output, "FIELD PrimaryData 12\n"); #define WRITE(Side, Name) { \ fprintf(output, STR(Side)"_"STR(Name)" 2 %zu float\n", n); \ - FOR_EACH(ircv, 0, sa_size(msh->entities)) { \ - NCHECK(rcv = find_receiver_by_id(simul, msh->entities[ircv]), NULL); \ - FOR_EACH(icell, 0, msh->ncells[ircv]) { \ + FOR_EACH(ircv, 0, BUF_SZ(msh->entities)) { \ + CHK(rcv = find_receiver_by_id(simul, BUF_AT(msh->entities, ircv))); \ + FOR_EACH(icell, 0, BUF_AT(msh->ncells, ircv)) { \ fprintf(output, "%g %g\n", rcv->Name[Side].E, rcv->Name[Side].SE); \ } \ } \ @@ -176,13 +177,13 @@ mesh_write_rcv_data_vtk #define WRITE_MAP(Side) { \ fprintf(output, STR(Side)"_map 2 %zu float\n", n); \ - FOR_EACH(ircv, 0, sa_size(msh->entities)) { \ - NCHECK(rcv = find_receiver_by_id(simul, msh->entities[ircv]), NULL); \ - if(!darray_mc_size_get(&rcv->map[Side])) { \ - FOR_EACH(icell, 0, msh->ncells[ircv]) fprintf(output, "-1 -1\n"); \ + FOR_EACH(ircv, 0, BUF_SZ(msh->entities)) { \ + CHK(rcv = find_receiver_by_id(simul, BUF_AT(msh->entities, ircv))); \ + if(!BUF_SZ(rcv->map[Side])) { \ + FOR_EACH(icell, 0, BUF_AT(msh->ncells,ircv)) fprintf(output,"-1 -1\n");\ } else { \ - FOR_EACH(icell, 0, msh->ncells[ircv]) { \ - const struct mc* mc = darray_mc_cdata_get(&rcv->map[Side])+icell; \ + FOR_EACH(icell, 0, BUF_AT(msh->ncells,ircv)) { \ + const struct mc* mc = &BUF_AT(rcv->map[Side], icell); \ fprintf(output, "%g %g\n", mc->E, mc->SE); \ } \ } \ @@ -196,31 +197,25 @@ mesh_write_rcv_data_vtk int main(int argc, char** argv) { - char* buf = NULL; + buf_char_T buf = BUF_NULL; char* line = NULL; - char* str = NULL; - - struct simul simul; - struct str name; FILE* input; FILE* geom; FILE* output; - simul_init(NULL, &simul); - str_init(NULL, &name); - if(argc < 3) { fprintf(stderr, "Usage: %s solstice-geometry solstice-simulation\n", argv[0]); return 1; } - NCHECK(geom = fopen(argv[1], "r"), NULL); - NCHECK(input = fopen(argv[2], "r"), NULL); - - NCHECK(read_line(&buf, geom), NULL); /* Skip the sun direction of the geometry */ + CHK(geom = fopen(argv[1], "r")); + CHK(input = fopen(argv[2], "r")); + CHK(read_line(&buf, geom)); /* Skip the sun direction of the geometry */ while((line = read_line(&buf, input))) { + struct simul simul; + const struct rcv* rcv = NULL; const struct prim* prim = NULL; @@ -233,30 +228,29 @@ main(int argc, char** argv) size_t ntris_grp = 0, nverts_grp = 0; size_t nverts_obj = 0, off_obj = 0, off_grp = 0; - simul_clear(&simul); + simul_init(&simul); - CHECK(strncmp(line, "#--- Sun direction:", 19), 0); - CHECK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &simul.azimuth, &simul.elevation), 2); - CHECK(snprintf(prefix, sizeof(prefix), "%g-%g-", - simul.azimuth, simul.elevation) < sizeof(prefix), 1); + CHK(!strncmp(line, "#--- Sun direction:", 19)); + CHK(sscanf(line+19, "%lf %lf (%*f %*f %*f)", &simul.azimuth, &simul.elevation)==2); + CHK(snprintf(prefix, sizeof(prefix), "%g-%g-", + simul.azimuth, simul.elevation) < sizeof(prefix)); read_simulation(&simul, input); while((line = read_line(&buf, geom)) && strncmp(line, "#--- Sun", 8)) { if(!strncmp(line, "g ", 2)) { - CHECK(str_set(&name, line+2), RES_OK); if(prim) { - sa_push(msh_prim.ncells, ntris_grp); + BUF_PUSH(msh_prim.ncells, ntris_grp); msh_prim.voffset += nverts_grp; } if(rcv) { - sa_push(msh_rcv.ncells, ntris_grp); + BUF_PUSH(msh_rcv.ncells, ntris_grp); msh_rcv.voffset += nverts_grp; } if(!prim && !rcv) msh_misc.voffset += nverts_grp; prim = find_primary(&simul, line+2); rcv = find_receiver(&simul, line+2); - if(prim) sa_push(msh_prim.entities, prim->id); - if(rcv) sa_push(msh_rcv.entities, rcv->id); + if(prim) BUF_PUSH(msh_prim.entities, prim->id); + if(rcv) BUF_PUSH(msh_rcv.entities, rcv->id); ntris_grp = 0; nverts_grp = 0; off_grp = 0; @@ -264,41 +258,41 @@ main(int argc, char** argv) } else if(!strncmp(line, "v ", 2)) { double pos[3]; - CHECK(sscanf(line+2, "%lf %lf %lf", pos+0, pos+1, pos+2), 3); + CHK(sscanf(line+2, "%lf %lf %lf", pos+0, pos+1, pos+2) == 3); if(prim) { - sa_push(msh_prim.coords, pos[0]); - sa_push(msh_prim.coords, pos[1]); - sa_push(msh_prim.coords, pos[2]); + BUF_PUSH(msh_prim.coords, pos[0]); + BUF_PUSH(msh_prim.coords, pos[1]); + BUF_PUSH(msh_prim.coords, pos[2]); } if(rcv) { - sa_push(msh_rcv.coords, pos[0]); - sa_push(msh_rcv.coords, pos[1]); - sa_push(msh_rcv.coords, pos[2]); + BUF_PUSH(msh_rcv.coords, pos[0]); + BUF_PUSH(msh_rcv.coords, pos[1]); + BUF_PUSH(msh_rcv.coords, pos[2]); } if(!prim && !rcv) { - sa_push(msh_misc.coords, pos[0]); - sa_push(msh_misc.coords, pos[1]); - sa_push(msh_misc.coords, pos[2]); + BUF_PUSH(msh_misc.coords, pos[0]); + BUF_PUSH(msh_misc.coords, pos[1]); + BUF_PUSH(msh_misc.coords, pos[2]); } ++nverts_grp; ++nverts_obj; } else if(!strncmp(line, "f ", 2)) { size_t tri[3]; - CHECK(sscanf(line+2, "%zu %zu %zu", tri+0, tri+1, tri+2), 3); + CHK(sscanf(line+2, "%zu %zu %zu", tri+0, tri+1, tri+2) == 3); if(prim) { - sa_push(msh_prim.ids, tri[0]-1 + msh_prim.voffset + off_grp - off_obj); - sa_push(msh_prim.ids, tri[1]-1 + msh_prim.voffset + off_grp - off_obj); - sa_push(msh_prim.ids, tri[2]-1 + msh_prim.voffset + off_grp - off_obj); + BUF_PUSH(msh_prim.ids, tri[0]-1 + msh_prim.voffset + off_grp - off_obj); + BUF_PUSH(msh_prim.ids, tri[1]-1 + msh_prim.voffset + off_grp - off_obj); + BUF_PUSH(msh_prim.ids, tri[2]-1 + msh_prim.voffset + off_grp - off_obj); } if(rcv) { - sa_push(msh_rcv.ids, tri[0]-1 + msh_rcv.voffset + off_grp - off_obj); - sa_push(msh_rcv.ids, tri[1]-1 + msh_rcv.voffset + off_grp - off_obj); - sa_push(msh_rcv.ids, tri[2]-1 + msh_rcv.voffset + off_grp - off_obj); + BUF_PUSH(msh_rcv.ids, tri[0]-1 + msh_rcv.voffset + off_grp - off_obj); + BUF_PUSH(msh_rcv.ids, tri[1]-1 + msh_rcv.voffset + off_grp - off_obj); + BUF_PUSH(msh_rcv.ids, tri[2]-1 + msh_rcv.voffset + off_grp - off_obj); } if(!prim && !rcv) { - sa_push(msh_misc.ids, tri[0]-1 + msh_misc.voffset + off_grp - off_obj); - sa_push(msh_misc.ids, tri[1]-1 + msh_misc.voffset + off_grp - off_obj); - sa_push(msh_misc.ids, tri[2]-1 + msh_misc.voffset + off_grp - off_obj); + BUF_PUSH(msh_misc.ids, tri[0]-1 + msh_misc.voffset + off_grp - off_obj); + BUF_PUSH(msh_misc.ids, tri[1]-1 + msh_misc.voffset + off_grp - off_obj); + BUF_PUSH(msh_misc.ids, tri[2]-1 + msh_misc.voffset + off_grp - off_obj); } ++ntris_grp; } else if(!strcmp(line, "---")) { @@ -307,40 +301,38 @@ main(int argc, char** argv) off_grp = nverts_grp; } } - if(prim) sa_push(msh_prim.ncells, ntris_grp); - if(rcv) sa_push(msh_rcv.ncells, ntris_grp); + if(prim) BUF_PUSH(msh_prim.ncells, ntris_grp); + if(rcv) BUF_PUSH(msh_rcv.ncells, ntris_grp); - CHECK(snprintf(filename, sizeof(filename), - "%sprimaries.vtk", prefix) < sizeof(prefix), 1); - NCHECK(output = fopen(filename, "w"), NULL); + CHK(snprintf(filename, sizeof(filename), + "%sprimaries.vtk", prefix) < sizeof(prefix)); + CHK(output = fopen(filename, "w")); mesh_write_vtk(output, &msh_prim); mesh_write_prim_data_vtk(output, &msh_prim, &simul); fclose(output); - CHECK(snprintf(filename, sizeof(filename), - "%sreceivers.vtk", prefix) < sizeof(prefix), 1); - NCHECK(output = fopen(filename, "w"), NULL); + CHK(snprintf(filename, sizeof(filename), + "%sreceivers.vtk", prefix) < sizeof(prefix)); + CHK(output = fopen(filename, "w")); mesh_write_vtk(output, &msh_rcv); mesh_write_rcv_data_vtk(output, &msh_rcv, &simul); fclose(output); - CHECK(snprintf(filename, sizeof(filename), - "%smiscellaneous.obj", prefix) < sizeof(prefix), 1); - NCHECK(output = fopen(filename, "w"), NULL); + CHK(snprintf(filename, sizeof(filename), + "%smiscellaneous.obj", prefix) < sizeof(prefix)); + CHK(output = fopen(filename, "w")); mesh_write_obj(output, &msh_misc); fclose(output); mesh_release(&msh_prim); mesh_release(&msh_rcv); mesh_release(&msh_misc); + simul_release(&simul); } fclose(geom); fclose(input); - sa_release(buf); - sa_release(str); - simul_release(&simul); - str_release(&name); + BUF_RELEASE(buf); return 0; }